diff --git a/package-lock.json b/package-lock.json index 1b5a135c0..5052e5116 100644 --- a/package-lock.json +++ b/package-lock.json @@ -881,12 +881,12 @@ }, "dependencies": { "browserslist": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.7.tgz", - "integrity": "sha512-oYVLxFVqpX9uMhOIQBLtZL+CX4uY8ZpWcjNTaxyWl5rO8yA9SSNikFnAfvk8J3P/7z3BZwNmEqFKaJoYltj3MQ==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", "requires": { - "caniuse-lite": "^1.0.30000835", - "electron-to-chromium": "^1.3.45" + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" } } } @@ -1983,9 +1983,9 @@ } }, "@types/node": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.1.1.tgz", - "integrity": "sha512-n7wxy8r2tjVcrzZoKJlyZmi1C1VhXGHAGhDEO1iqp7fbsTSsDF3dVA50KFsPg77EXqzNJqbzcna8Mi4m7a1lyw==" + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.1.2.tgz", + "integrity": "sha512-bjk1RIeZBCe/WukrFToIVegOf91Pebr8cXYBwLBIsfiGWVQ+ifwWsT59H3RxrWzWrzd1l/Amk1/ioY5Fq3/bpA==" }, "abab": { "version": "1.0.4", @@ -2066,14 +2066,15 @@ } }, "airbnb-js-shims": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/airbnb-js-shims/-/airbnb-js-shims-1.4.1.tgz", - "integrity": "sha512-b7S3d+DPRMwaDAs0cgKQTMLO/JG/iSehIlzEGvt2FpxIztRDDABEjWI73AfTxkSiK3/OsraPRYxVNAX3yhSNLw==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/airbnb-js-shims/-/airbnb-js-shims-1.5.1.tgz", + "integrity": "sha512-Dqk+NEHgxuHNAt5FWKmwWsR9Q1dRonVzWTmDs1fhX1L/Rwi8R0ZYzrPHsCveg/AnrKM64RlAkXOiYnEtbWZcXA==", "dev": true, "requires": { "array-includes": "^3.0.3", - "array.prototype.flatmap": "^1.2.0", - "array.prototype.flatten": "^1.2.0", + "array.prototype.flat": "^1.2.1", + "array.prototype.flatmap": "^1.2.1", + "array.prototype.flatten": "^1.2.1", "es5-shim": "^4.5.10", "es6-shim": "^0.35.3", "function.prototype.name": "^1.1.0", @@ -2082,7 +2083,8 @@ "object.values": "^1.0.4", "promise.prototype.finally": "^3.1.0", "string.prototype.padend": "^3.0.0", - "string.prototype.padstart": "^3.0.0" + "string.prototype.padstart": "^3.0.0", + "symbol.prototype.description": "^1.0.0" } }, "ajv": { @@ -2363,6 +2365,17 @@ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, + "array.prototype.flat": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.1.tgz", + "integrity": "sha512-rVqIs330nLJvfC7JqYvEWwqVr5QjYF1ib02i3YJtR/fICO6527Tjpc/e4Mvmxh3GIePPreRXMdaGyC99YphWEw==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.10.0", + "function-bind": "^1.1.1" + } + }, "array.prototype.flatmap": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.1.tgz", @@ -2440,11 +2453,11 @@ "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=" }, "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "requires": { - "lodash": "^4.14.0" + "lodash": "^4.17.10" } }, "async-each": { @@ -4103,14 +4116,6 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, - "boom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", - "requires": { - "hoek": "4.x.x" - } - }, "bowser": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.3.tgz", @@ -4464,14 +4469,14 @@ } }, "caniuse-db": { - "version": "1.0.30000843", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000843.tgz", - "integrity": "sha1-T36FAfVX3JvNN90zrIWQXHZe/sI=" + "version": "1.0.30000844", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000844.tgz", + "integrity": "sha1-vKV5jNoraTHWgQDC1p5V+zOMu0E=" }, "caniuse-lite": { - "version": "1.0.30000843", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000843.tgz", - "integrity": "sha512-1ntiW826MhRBmM0CeI7w1cQr16gxwOoM8doJWh3BFalPZoKWdZXs27Bc04xth/3NR1/wNXn9cpP4F92lVenCvg==" + "version": "1.0.30000844", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000844.tgz", + "integrity": "sha512-UpKQE7y6dLHhlv75UyBCRiun34Q+bmxyX3zS+ve9M07YG52tRafOvop9N9d5jC+sikKuG7UMweJKJNts4FVehA==" }, "capture-stack-trace": { "version": "1.0.0", @@ -5069,24 +5074,6 @@ "which": "^1.2.9" } }, - "cryptiles": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", - "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", - "requires": { - "boom": "5.x.x" - }, - "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "requires": { - "hoek": "4.x.x" - } - } - } - }, "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -5853,9 +5840,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.47", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.47.tgz", - "integrity": "sha1-dk6IfKkQTQGgrI6r7n38DizhQQQ=" + "version": "1.3.48", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.48.tgz", + "integrity": "sha1-07DYWTgUBE4JLs4hCPw6ya6kuQA=" }, "elliptic": { "version": "6.4.0", @@ -7142,9 +7129,9 @@ } }, "follow-redirects": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.4.1.tgz", - "integrity": "sha512-uxYePVPogtya1ktGnAAXOacnbIuRMB4dkvqeNz2qTtTQsuzSfbDolV+wMMKxAmCx0bLgAKLbBOkjItMbbkR1vg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.0.tgz", + "integrity": "sha512-fdrt472/9qQ6Kgjvb935ig6vJCuofpBUD14f9Vb+SLlm7xIe4Qva5gey8EKtv8lp7ahE1wilg3xL1znpVGtZIA==", "requires": { "debug": "^3.1.0" }, @@ -8240,17 +8227,6 @@ "minimalistic-assert": "^1.0.0" } }, - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", - "requires": { - "boom": "4.x.x", - "cryptiles": "3.x.x", - "hoek": "4.x.x", - "sntp": "2.x.x" - } - }, "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", @@ -8278,11 +8254,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "hoek": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" - }, "hoist-non-react-statics": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz", @@ -8359,9 +8330,9 @@ } }, "html-minifier": { - "version": "3.5.15", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.15.tgz", - "integrity": "sha512-OZa4rfb6tZOZ3Z8Xf0jKxXkiDcFWldQePGYFDcgKqES2sXeWaEv9y6QQvWUtX3ySI3feApQi5uCsHLINQ6NoAw==", + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.16.tgz", + "integrity": "sha512-zP5EfLSpiLRp0aAgud4CQXPQZm9kXwWjR/cF0PfdOj+jjWnOaCgeZcll4kYXSvIBPeUMmyaSc7mM4IDtA+kboA==", "requires": { "camel-case": "3.0.x", "clean-css": "4.1.x", @@ -8434,9 +8405,9 @@ } }, "http-parser-js": { - "version": "0.4.12", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.12.tgz", - "integrity": "sha1-uc+/Sizybw/DSxDKFImid3HjR08=" + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.13.tgz", + "integrity": "sha1-O9bW/ebjFyyTNMOzO2wZPYD+ETc=" }, "http-proxy": { "version": "1.17.0", @@ -8830,13 +8801,6 @@ "pull-stream": "^3.6.7", "pull-traverse": "^1.0.3", "stable": "0.1.6" - }, - "dependencies": { - "stable": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.6.tgz", - "integrity": "sha1-kQ9dKu17Ugxud3SZwfMuE5/eyxA=" - } } }, "is-absolute-url": { @@ -8867,6 +8831,11 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, + "is-binary": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-binary/-/is-binary-0.1.0.tgz", + "integrity": "sha1-jn0yenq5B6g4+BE+nOUWjf2786s=" + }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", @@ -9118,9 +9087,9 @@ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" }, "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz", + "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=" }, "is-redirect": { "version": "1.0.0", @@ -10372,11 +10341,6 @@ "yallist": "^2.1.2" } }, - "macaddress": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz", - "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=" - }, "make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", @@ -10915,11 +10879,6 @@ "promise": "~1.3.0" }, "dependencies": { - "is-promise": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz", - "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=" - }, "promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/promise/-/promise-1.3.0.tgz", @@ -12024,12 +11983,11 @@ } }, "postcss-filter-plugins": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz", - "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz", + "integrity": "sha512-T53GVFsdinJhgwm7rg1BzbeBRomOg9y5MBVhGcsV0CxurUdVj1UlPdKtn7aqYA/c/QVkzKMjq2bSV5dKG5+AwQ==", "requires": { - "postcss": "^5.0.4", - "uniqid": "^4.0.0" + "postcss": "^5.0.4" }, "dependencies": { "has-flag": { @@ -13017,9 +12975,9 @@ } }, "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "puppeteer": { "version": "1.4.0", @@ -13877,9 +13835,9 @@ } }, "redux-bundler": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/redux-bundler/-/redux-bundler-21.2.0.tgz", - "integrity": "sha512-wcpvm5JY7JvW6/ABiAmzf9/TvXAWUElOaj18zRWQELDiPrc44VoJFShNGTtvf9xungDwBuvwU4oaVxsWTdlPSA==" + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/redux-bundler/-/redux-bundler-21.2.1.tgz", + "integrity": "sha512-iQtUq0vtoUfgNX0Fl7Wu4YngbQpJ+2OdVp476dPhuH+zaLqtZRc24mY3x5qaYsIMY9xaDfZLLUGu35z/YLuh3w==" }, "redux-bundler-react": { "version": "1.0.0", @@ -14080,9 +14038,9 @@ } }, "request": { - "version": "2.86.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.86.0.tgz", - "integrity": "sha512-BQZih67o9r+Ys94tcIW4S7Uu8pthjrQVxhsZ/weOwHbDfACxvIyvnAbzFQxjy1jMtvFSzv5zf4my6cZsJBbVzw==", + "version": "2.87.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", + "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.6.0", @@ -14092,7 +14050,6 @@ "forever-agent": "~0.6.1", "form-data": "~2.3.1", "har-validator": "~5.0.3", - "hawk": "~6.0.2", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", @@ -14255,6 +14212,13 @@ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", "requires": { "is-promise": "^2.1.0" + }, + "dependencies": { + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + } } }, "run-parallel": { @@ -14694,14 +14658,6 @@ } } }, - "sntp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", - "requires": { - "hoek": "4.x.x" - } - }, "sockjs": { "version": "0.3.18", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.18.tgz", @@ -14920,9 +14876,9 @@ } }, "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.6.tgz", + "integrity": "sha1-kQ9dKu17Ugxud3SZwfMuE5/eyxA=" }, "standard": { "version": "11.0.1", @@ -15591,6 +15547,15 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" }, + "symbol.prototype.description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/symbol.prototype.description/-/symbol.prototype.description-1.0.0.tgz", + "integrity": "sha512-I9mrbZ5M96s7QeJDv95toF1svkUjeBybe8ydhY7foPaBmr0SPJMFupArmMkDrOKTTj0sJVr+nvQNxWLziQ7nDQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, "table": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", @@ -15886,9 +15851,9 @@ "integrity": "sha512-LtzwHlVHwFGTptfNSgezHp7WUlwiqb0gA9AALRbKaERfxwJoiX0A73QbTToxteIAuIaFshhgIZfqK8s7clqgnA==" }, "uglify-js": { - "version": "3.3.25", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.25.tgz", - "integrity": "sha512-hobogryjDV36VrLK3Y69ou4REyrTApzUblVFmdQOYRe8cYaSmFJXMb4dR9McdvYDSbeNdzUgYr2YVukJaErJcA==", + "version": "3.3.27", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.27.tgz", + "integrity": "sha512-O94wxMSb3td/TlofkITYvYIlvIVdldvNXDVRekzK13CQZuL37ua4nrdXX0Ro7MapfUVzglRHs0/+imPRUdOghg==", "requires": { "commander": "~2.15.0", "source-map": "~0.6.1" @@ -16028,14 +15993,6 @@ "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" }, - "uniqid": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz", - "integrity": "sha1-iSIN32t1GuUrX3JISGNShZa7hME=", - "requires": { - "macaddress": "^0.2.8" - } - }, "uniqs": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", diff --git a/package.json b/package.json index fa955cf6d..44d00a073 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "ipfs-css": "^0.5.0", "ipld-dag-pb": "^0.14.3", "ipfs-unixfs": "^0.1.14", + "is-binary": "^0.1.0", "milliseconds": "^1.0.3", "multibase": "^0.4.0", "multicodec": "^0.2.6", diff --git a/src/App.js b/src/App.js index 1e2f4535a..833952798 100644 --- a/src/App.js +++ b/src/App.js @@ -45,4 +45,9 @@ export class App extends Component { } } -export default connect('selectRoute', 'doUpdateUrl', 'doInitIpfs', App) +export default connect( + 'selectRoute', + 'doUpdateUrl', + 'doInitIpfs', + App +) diff --git a/src/App.test.js b/src/App.test.js index 3a2927b72..4bb8ba76d 100644 --- a/src/App.test.js +++ b/src/App.test.js @@ -19,7 +19,7 @@ it('example test', async () => { let titleText = await page.evaluate(el => el.innerHTML, title) expect(titleText).toBe('Status') - await page.click('nav a[href="#/files"]') + await page.click('nav a[href="#/files/"]') title = await page.$('[data-id=title]') titleText = await page.evaluate(el => el.innerHTML, title) diff --git a/src/bundles/files.js b/src/bundles/files.js new file mode 100644 index 000000000..22db00ff8 --- /dev/null +++ b/src/bundles/files.js @@ -0,0 +1,146 @@ +import { createAsyncResourceBundle, createSelector } from 'redux-bundler' +import { join } from '../lib/path' + +const bundle = createAsyncResourceBundle({ + name: 'files', + actionBaseType: 'FILES', + getPromise: (args) => { + const {store, getIpfs} = args + let path = store.selectRouteParams().path + + if (!path) { + store.doUpdateHash('/files/') + return Promise.resolve() + } + + // FIX: dirs with actually encoded names + // will get decoded... it shouldn't happen + path = decodeURIComponent(path) + + return getIpfs().files.stat(path) + .then(stats => { + if (stats.type === 'directory') { + return getIpfs().files.ls(path, {l: true}).then((res) => { + // FIX: open PR on js-ipfs-api + if (res) { + res = res.map(file => { + file.type = file.type === 0 ? 'file' : 'directory' + return file + }) + } + + return { + path: path, + type: 'directory', + files: res + } + }) + } else { + stats.name = path + + return { + path: path, + type: 'file', + stats: stats, + read: () => getIpfs().files.read(path) + } + } + }) + }, + staleAfter: 100, + checkIfOnline: false +}) + +bundle.reactFilesFetch = createSelector( + 'selectFilesShouldUpdate', + 'selectIpfsReady', + 'selectRouteInfo', + 'selectFiles', + (shouldUpdate, ipfsReady, {url, params}, files) => { + if (shouldUpdate && ipfsReady && url.startsWith('/files')) { + if (!files || files.path !== params.path) { + return { actionCreator: 'doFetchFiles' } + } + } + } +) + +bundle.doFilesDelete = (files) => ({dispatch, getIpfs, store}) => { + dispatch({ type: 'FILES_DELETE_STARTED' }) + + const promises = files.map(file => getIpfs().files.rm(file, { recursive: true })) + Promise.all(promises) + .then(() => { + store.doFetchFiles() + dispatch({ type: 'FILES_DELETE_FINISHED' }) + }) + .catch((error) => { + dispatch({ type: 'FILES_DELETE_ERRORED', payload: error }) + }) +} + +function runAndFetch ({ dispatch, getIpfs, store }, type, action, args) { + dispatch({ type: `${type}_STARTED` }) + + return getIpfs().files[action](...args) + .then(() => { + store.doFetchFiles() + dispatch({ type: `${type}_FINISHED` }) + }) + .catch((error) => { + dispatch({ type: `${type}_ERRORED`, payload: error }) + }) +} + +bundle.doFilesRename = (from, to) => (args) => { + runAndFetch(args, 'FILES_RENAME', 'mv', [[from, to]]) +} + +bundle.doFilesCopy = (from, to) => (args) => { + runAndFetch(args, 'FILES_RENAME', 'cp', [[from, to]]) +} + +bundle.doFilesMakeDir = (path) => (args) => { + runAndFetch(args, 'FILES_MKDIR', 'mkdir', [path, { parents: true }]) +} + +function readAsBuffer (file) { + return new Promise((resolve, reject) => { + const reader = new window.FileReader() + reader.onload = (event) => { + resolve({ + content: Buffer.from(reader.result), + name: file.name + }) + } + reader.onerror = (event) => { + reject(reader.error) + } + + reader.readAsArrayBuffer(file) + }) +} + +bundle.doFilesWrite = (root, files) => ({dispatch, getIpfs, store}) => { + dispatch({ type: 'FILES_WRITE_STARTED' }) + + let promises = [] + + for (const file of files) { + promises.push(readAsBuffer(file)) + } + + return Promise.all(promises).then(files => { + return Promise.all(files.map((file) => { + const target = join(root, file.name) + return getIpfs().files.write(target, file.content, { create: true }) + })) + }).then(() => { + store.doFetchFiles() + dispatch({ type: 'FILES_WRITE_FINISHED' }) + }).catch((error) => { + dispatch({ type: 'FILES_WRITE_ERRORED', payload: error }) + }) +} + +export default bundle diff --git a/src/bundles/index.js b/src/bundles/index.js index 3c33673a5..c1b261ab6 100644 --- a/src/bundles/index.js +++ b/src/bundles/index.js @@ -6,6 +6,7 @@ import appIdle from './app-idle' import peersBundle from './peers' import routesBundle from './routes' import redirectsBundle from './redirects' +import filesBundle from './files' export default composeBundles( appIdle({idleTimeout: 5000}), @@ -13,5 +14,6 @@ export default composeBundles( objectBundle, peersBundle, routesBundle, - redirectsBundle + redirectsBundle, + filesBundle ) diff --git a/src/bundles/ipfs.js b/src/bundles/ipfs.js index d3c3c221a..49bf0f5b3 100644 --- a/src/bundles/ipfs.js +++ b/src/bundles/ipfs.js @@ -8,6 +8,15 @@ export default { if (action.type === 'IPFS_INIT_FINISHED') { return { ...state, ipfsReady: true } } + + if (action.type === 'IPFS_GATEWAY_URL_FINISHED') { + return { ...state, gatewayUrl: action.payload } + } + + if (!state.gatewayUrl) { + return { ...state, gatewayUrl: 'https://ipfs.io' } + } + return state }, @@ -17,7 +26,9 @@ export default { selectIpfsReady: state => state.ipfs.ipfsReady, - doInitIpfs: () => async ({ dispatch }) => { + selectGatewayUrl: state => state.ipfs.gatewayUrl, + + doInitIpfs: () => async ({ dispatch, store }) => { dispatch({ type: 'IPFS_INIT_STARTED' }) try { @@ -26,6 +37,23 @@ export default { return dispatch({ type: 'IPFS_INIT_FAILED', payload: err }) } + store.doGetGatewayUrl() dispatch({ type: 'IPFS_INIT_FINISHED' }) + }, + + doGetGatewayUrl: () => async ({ dispatch, getIpfs }) => { + dispatch({ type: 'IPFS_GATWAY_URL_STARTED' }) + + getIpfs().config.get('Addresses.Gateway', (err, res) => { + if (err) { + dispatch({ type: 'IPFS_GATWAY_URL_ERRORED', payload: err }) + return + } + + const split = res.split('/') + const gateway = '//' + split[2] + ':' + split[4] + + dispatch({ type: 'IPFS_GATWAY_URL_FINISHED', payload: gateway }) + }) } } diff --git a/src/bundles/routes.js b/src/bundles/routes.js index 20d1a0933..12dddb080 100644 --- a/src/bundles/routes.js +++ b/src/bundles/routes.js @@ -8,6 +8,7 @@ import SettingsPage from '../settings/SettingsPage' export default createRouteBundle({ '/files': FilesPage, '/explore*': IpldPage, + '/files*': FilesPage, '/peers': PeersPage, '/settings': SettingsPage, '/': StatusPage, diff --git a/src/files/FilesPage.js b/src/files/FilesPage.js index 83a779c6d..db24c732d 100644 --- a/src/files/FilesPage.js +++ b/src/files/FilesPage.js @@ -1,2 +1,106 @@ import React from 'react' -export default () =>

Files

+import PropTypes from 'prop-types' +import { connect } from 'redux-bundler-react' +import Breadcrumbs from './breadcrumbs/Breadcrumbs' +import FilesList from './files-list/FilesList' +import FilePreview from './file-preview/FilePreview' +import FileInput from './file-input/FileInput' + +const action = (name) => { + return (...args) => { + console.log(name, args) + } +} + +const empty = ( +
+

It seems a bit lonely here :(

+
+) + +class FilesPage extends React.Component { + static propTypes = { + files: PropTypes.object + } + + state = { + clipboard: [], + copy: false + } + + onLinkClick = (link) => { + const {doUpdateHash} = this.props + doUpdateHash(`/files${link}`) + } + + onInspect = (hash) => { + const {doUpdateHash} = this.props + doUpdateHash(`/explore/ipfs/${hash}`) + } + + onRename = ([path]) => { + const oldName = path.split('/').pop() + const newName = window.prompt('Insert the new name:') + + if (newName) { + this.props.doFilesRename(path, path.replace(oldName, newName)) + } + } + + onFilesUpload = (files) => { + this.props.doFilesWrite(this.props.files.path, files) + } + + render () { + const {files} = this.props + + if (!files) { + return
+

Files

+
+ } + + let body + if (files.type === 'directory') { + if (files.files.length === 0) { + body = empty + } else { + body = + } + } else { + body = + } + + return ( +
+
+ + +
+ {body} +

Files

+
+ ) + } +} + +export default connect( + 'doUpdateHash', + 'doFilesDelete', + 'doFilesRename', + 'doFilesWrite', + 'selectFiles', + 'selectGatewayUrl', + FilesPage +) diff --git a/src/files/breadcrumbs/Breadcrumbs.js b/src/files/breadcrumbs/Breadcrumbs.js index b82950238..3ecd8bc18 100644 --- a/src/files/breadcrumbs/Breadcrumbs.js +++ b/src/files/breadcrumbs/Breadcrumbs.js @@ -14,8 +14,6 @@ function makeBread (root) { } }) - parts[0].name = 'Root' - for (let i = 1; i < parts.length; i++) { parts[i] = { name: parts[i].name, @@ -23,6 +21,9 @@ function makeBread (root) { } } + parts[0].name = 'Root' + parts[0].path = '/' + return parts } diff --git a/src/files/file-icon/FileIcon.js b/src/files/file-icon/FileIcon.js index cb270e314..7108d5561 100644 --- a/src/files/file-icon/FileIcon.js +++ b/src/files/file-icon/FileIcon.js @@ -1,11 +1,5 @@ import React from 'react' -import fileExtension from 'file-extension' - -import audioExtensions from './extensions/audio.json' -import calcExtensions from './extensions/calc.json' -import imageExtensions from './extensions/image.json' -import videoExtensions from './extensions/video.json' -import textExtensions from './extensions/text.json' +import typeFromExt from '../type-from-ext' import Folder from '../../icons/GlyphFolder' import Doc from '../../icons/StrokeDocument' @@ -16,23 +10,22 @@ import DocPicture from '../../icons/GlyphDocPicture' import DocText from '../../icons/GlyphDocText' export default function FileIcon ({name, type}) { - const ext = fileExtension(name) - if (type === 'directory') { return } - if (audioExtensions.includes(ext)) { - return - } else if (calcExtensions.includes(ext)) { - return - } else if (imageExtensions.includes(ext)) { - return - } else if (videoExtensions.includes(ext)) { - return - } else if (textExtensions.includes(ext)) { - return + switch (typeFromExt(name)) { + case 'audio': + return + case 'calc': + return + case 'video': + return + case 'text': + return + case 'image': + return + default: + return } - - return } diff --git a/src/files/file-icon/extensions/audio.json b/src/files/file-icon/extensions/audio.json deleted file mode 100644 index 617d45e24..000000000 --- a/src/files/file-icon/extensions/audio.json +++ /dev/null @@ -1,33 +0,0 @@ -[ - "wav", - "bwf", - "raw", - "aiff", - "flac", - "m4a", - "pac", - "tta", - "wv", - "ast", - "aac", - "mp2", - "mp3", - "mp4", - "amr", - "s3m", - "3gp", - "act", - "au", - "dct", - "dss", - "gsm", - "m4p", - "mmf", - "mpc", - "ogg", - "oga", - "opus", - "ra", - "sln", - "vox" -] \ No newline at end of file diff --git a/src/files/file-icon/extensions/calc.json b/src/files/file-icon/extensions/calc.json deleted file mode 100644 index 94229823b..000000000 --- a/src/files/file-icon/extensions/calc.json +++ /dev/null @@ -1,67 +0,0 @@ -[ - "123", - "12m", - "_xls", - "_xlsx", - "ast", - "aws", - "bks", - "cell", - "def", - "dex", - "dfg", - "dis", - "edx", - "edxz", - "ess", - "fcs", - "fm", - "fods", - "fp", - "gnm", - "gnumeric", - "gsheet", - "hcdt", - "imp", - "mar", - "nb", - "ncss", - "nmbtemplate", - "numbers", - "numbers-tef", - "ods", - "ogw", - "ogwu", - "ots", - "pmd", - "pmdx", - "pmv", - "pmvx", - "qpw", - "rdf", - "sdc", - "stc", - "sxc", - "tmv", - "tmvt", - "uos", - "wki", - "wkq", - "wks", - "wks", - "wku", - "wq1", - "wq2", - "xar", - "xl", - "xlr", - "xls", - "xlsb", - "xlshtml", - "xlsm", - "xlsmhtml", - "xlsx", - "xlthtml", - "xltm", - "xltx" -] \ No newline at end of file diff --git a/src/files/file-icon/extensions/image.json b/src/files/file-icon/extensions/image.json deleted file mode 100644 index b69acfab4..000000000 --- a/src/files/file-icon/extensions/image.json +++ /dev/null @@ -1,122 +0,0 @@ -[ - "ase", - "art", - "bmp", - "blp", - "cd5", - "cit", - "cpt", - "cr2", - "cut", - "dds", - "dib", - "djvu", - "egt", - "exif", - "gif", - "gpl", - "grf", - "icns", - "ico", - "iff", - "jng", - "jpeg", - "jpg", - "jfif", - "jp2", - "jps", - "lbm", - "max", - "miff", - "mng", - "msp", - "nitf", - "ota", - "pbm", - "pc1", - "pc2", - "pc3", - "pcf", - "pcx", - "pdn", - "pgm", - "PI1", - "PI2", - "PI3", - "pict", - "pct", - "pnm", - "pns", - "ppm", - "psb", - "psd", - "pdd", - "psp", - "px", - "pxm", - "pxr", - "qfx", - "raw", - "rle", - "sct", - "sgi", - "rgb", - "int", - "bw", - "tga", - "tiff", - "tif", - "vtf", - "xbm", - "xcf", - "xpm", - "3dv", - "amf", - "ai", - "awg", - "cgm", - "cdr", - "cmx", - "dxf", - "e2d", - "egt", - "eps", - "fs", - "gbr", - "odg", - "svg", - "stl", - "vrml", - "x3d", - "sxd", - "v2d", - "vnd", - "wmf", - "emf", - "art", - "xar", - "png", - "webp", - "jxr", - "hdp", - "wdp", - "cur", - "ecw", - "iff", - "lbm", - "liff", - "nrrd", - "pam", - "pcx", - "pgf", - "sgi", - "rgb", - "rgba", - "bw", - "int", - "inta", - "sid", - "ras", - "sun", - "tga" -] diff --git a/src/files/file-icon/extensions/text.json b/src/files/file-icon/extensions/text.json deleted file mode 100644 index ca39d122d..000000000 --- a/src/files/file-icon/extensions/text.json +++ /dev/null @@ -1,306 +0,0 @@ -[ - "1st", - "_doc", - "_docx", - "abw", - "act", - "adoc", - "aim", - "ans", - "apkg", - "apt", - "asc", - "asc", - "ascii", - "ase", - "aty", - "awp", - "awt", - "aww", - "bad", - "bbs", - "bdp", - "bdr", - "bean", - "bib", - "bib", - "bibtex", - "bml", - "bna", - "boc", - "brx", - "btd", - "bzabw", - "calca", - "charset", - "chart", - "chord", - "cnm", - "cod", - "crwl", - "cws", - "cyi", - "dca", - "dfti", - "dgs", - "diz", - "dne", - "doc", - "doc", - "docm", - "docx", - "docxml", - "docz", - "dox", - "dropbox", - "dsc", - "dvi", - "dwd", - "dx", - "dxb", - "dxp", - "eio", - "eit", - "emf", - "eml", - "emlx", - "emulecollection", - "epp", - "err", - "err", - "etf", - "etx", - "euc", - "fadein.template", - "faq", - "fbl", - "fcf", - "fdf", - "fdr", - "fds", - "fdt", - "fdx", - "fdxt", - "fft", - "fgs", - "flr", - "fodt", - "fountain", - "fpt", - "frt", - "fwd", - "fwdn", - "gmd", - "gpd", - "gpn", - "gsd", - "gthr", - "gv", - "hbk", - "hht", - "hs", - "hwp", - "hwp", - "hz", - "idx", - "iil", - "ipf", - "ipspot", - "jarvis", - "jis", - "jnp", - "joe", - "jp1", - "jrtf", - "jtd", - "kes", - "klg", - "klg", - "knt", - "kon", - "kwd", - "latex", - "lbt", - "lis", - "lnt", - "log", - "lp2", - "lst", - "lst", - "ltr", - "ltx", - "lue", - "luf", - "lwp", - "lxfml", - "lyt", - "lyx", - "man", - "mbox", - "mcw", - "md5.txt", - "me", - "mell", - "mellel", - "min", - "mnt", - "msg", - "mw", - "mwd", - "mwp", - "nb", - "ndoc", - "nfo", - "ngloss", - "njx", - "note", - "notes", - "now", - "nwctxt", - "nwm", - "nwp", - "ocr", - "odif", - "odm", - "odo", - "odt", - "ofl", - "opeico", - "openbsd", - "ort", - "ott", - "p7s", - "pages", - "pages-tef", - "pdpcmd", - "pfx", - "pjt", - "plain", - "plantuml", - "pmo", - "prt", - "prt", - "psw", - "pu", - "pvj", - "pvm", - "pwd", - "pwdp", - "pwdpl", - "pwi", - "pwr", - "qdl", - "qpf", - "rad", - "readme", - "rft", - "ris", - "rpt", - "rst", - "rtd", - "rtf", - "rtfd", - "rtx", - "run", - "rvf", - "rzk", - "rzn", - "saf", - "safetext", - "sam", - "sam", - "save", - "scc", - "scm", - "scriv", - "scrivx", - "sct", - "scw", - "sdm", - "sdoc", - "sdw", - "se", - "session", - "sgm", - "sig", - "skcard", - "sla", - "sla.gz", - "smf", - "sms", - "ssa", - "story", - "strings", - "stw", - "sty", - "sublime-project", - "sublime-workspace", - "sxg", - "sxw", - "tab", - "tab", - "tdf", - "tdf", - "template", - "tex", - "text", - "textclipping", - "thp", - "tlb", - "tm", - "tmd", - "tmdx", - "tmv", - "tmvx", - "tpc", - "trelby", - "tvj", - "txt", - "u3i", - "unauth", - "unx", - "uof", - "uot", - "upd", - "utf8", - "utxt", - "vct", - "vnt", - "vw", - "wbk", - "webdoc", - "wn", - "wp", - "wp4", - "wp5", - "wp6", - "wp7", - "wpa", - "wpd", - "wpd", - "wpd", - "wpl", - "wps", - "wps", - "wpt", - "wpt", - "wpw", - "wri", - "wsd", - "wtt", - "wtx", - "xbdoc", - "xbplate", - "xdl", - "xdl", - "xwp", - "xwp", - "xwp", - "xy", - "xy3", - "xyp", - "xyw", - "zabw", - "zrtf", - "zw" -] \ No newline at end of file diff --git a/src/files/file-icon/extensions/video.json b/src/files/file-icon/extensions/video.json deleted file mode 100644 index 0ad84d79f..000000000 --- a/src/files/file-icon/extensions/video.json +++ /dev/null @@ -1,35 +0,0 @@ -[ - "3g2", - "3gp", - "aaf", - "asf", - "avchd", - "avi", - "drc", - "flv", - "m2v", - "m4p", - "m4v", - "mkv", - "mng", - "mov", - "mp2", - "mp4", - "mpe", - "mpeg", - "mpg", - "mpv", - "mxf", - "nsv", - "ogg", - "ogv", - "qt", - "rm", - "rmvb", - "roq", - "svi", - "vob", - "webm", - "wmv", - "yuv" -] diff --git a/src/files/file-input/FileInput.js b/src/files/file-input/FileInput.js new file mode 100644 index 000000000..81dcbc9f8 --- /dev/null +++ b/src/files/file-input/FileInput.js @@ -0,0 +1,32 @@ +import React from 'react' +import PropTypes from 'prop-types' +import Button from '../../components/button/Button' + +export default class FileInput extends React.Component { + static propTypes = { + upload: PropTypes.func.isRequired + } + + onChange = () => { + this.props.upload(this.input.files) + this.input.value = null + } + + onClick = () => { + this.input.click() + } + + render () { + return ( +
+ + { this.input = input }} + onChange={this.onChange} /> +
+ ) + } +} diff --git a/src/files/file-preview/FilePreview.js b/src/files/file-preview/FilePreview.js new file mode 100644 index 000000000..f9e5732a5 --- /dev/null +++ b/src/files/file-preview/FilePreview.js @@ -0,0 +1,84 @@ +import React from 'react' +import PropTypes from 'prop-types' +import isBinary from 'is-binary' +import fileExtension from 'file-extension' +import typeFromExt from '../type-from-ext' + +class FilesPreview extends React.Component { + static propTypes = { + stats: PropTypes.object.isRequired, + gatewayUrl: PropTypes.string.isRequired, + read: PropTypes.func.isRequired, + content: PropTypes.object + } + + state = { + content: null + } + + loadContent () { + this.props.read() + .then(buf => { + this.setState({ content: buf.toString('utf-8') }) + }) + } + + render () { + const {stats, gatewayUrl} = this.props + + const type = typeFromExt(stats.name) + const src = `${gatewayUrl}/ipfs/${stats.hash}` + const ext = fileExtension(stats.name) + const className = 'w-100 bg-snow-muted pa2 br2' + switch (type) { + case 'audio': + return ( + + ) + case 'pdf': + return ( + + If you're seeing this, is because your browser doesn't support previwing + PDF files. + + ) + case 'video': + return ( + + ) + case 'image': + return {stats.name} + default: + const cantPreview = ( +
+ Sorry, we can not preview this file.. +
+ ) + + if (stats.size > 1024 * 1024 * 4) { + return cantPreview + } + + if (!this.state.content) { + this.loadContent() + return
Loading
+ } + + if (isBinary(this.state.content)) { + return cantPreview + } + + return ( +
+            {this.state.content}
+          
+ ) + } + } +} + +export default FilesPreview diff --git a/src/files/files-list/FilesList.js b/src/files/files-list/FilesList.js index 469c8a3b2..c621462ac 100644 --- a/src/files/files-list/FilesList.js +++ b/src/files/files-list/FilesList.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types' import Checkbox from '../../components/checkbox/Checkbox' import SelectedActions from '../selected-actions/SelectedActions' import File from '../file/File' +import { join } from '../../lib/path' import './FilesList.css' const ORDER_BY_NAME = 'name' @@ -18,12 +19,6 @@ function compare (a, b, asc) { } } -function join (a, b) { - if (a.endsWith('/')) a = a.slice(0, -1) - if (b.startsWith('/')) b = b.slice(1) - return `${a}/${b}` -} - class FileList extends React.Component { static propTypes = { className: PropTypes.string, @@ -35,11 +30,13 @@ class FileList extends React.Component { onNavigate: PropTypes.func.isRequired, onCancelUpload: PropTypes.func.isRequired, files: PropTypes.array.isRequired, - root: PropTypes.string.isRequired + root: PropTypes.string.isRequired, + maxWidth: PropTypes.string } static defaultProps = { - className: '' + className: '', + maxWidth: '100%' } state = { @@ -70,9 +67,20 @@ class FileList extends React.Component { this.setState({selected: selected}) } - genActionFromSelected = (fn) => { + genActionFromSelected = (fn, opts = {}) => { return () => { - this.props[fn](this.selectedFiles.map(f => join(this.props.root, f.name))) + if (opts.unselect) { + this.setState({ selected: [] }) + } + + let data + if (opts.hash) { + data = this.selectedFiles.map(f => f.hash) + } else { + data = this.selectedFiles.map(f => join(this.props.root, f.name)) + } + + this.props[fn](data) } } @@ -99,12 +107,13 @@ class FileList extends React.Component { return ( @@ -132,7 +141,7 @@ class FileList extends React.Component { onNavigate={this.genActionFromFile('onNavigate', file)} onCancel={this.genActionFromFile('onCancelUpload', file)} selected={this.state.selected.indexOf(file.hash) !== -1} - key={file.hash} + key={window.btoa(file.name)} {...file} /> )) diff --git a/src/files/selected-actions/SelectedActions.js b/src/files/selected-actions/SelectedActions.js index 63e7f544c..8aa1e0175 100644 --- a/src/files/selected-actions/SelectedActions.js +++ b/src/files/selected-actions/SelectedActions.js @@ -12,10 +12,20 @@ import './SelectedActions.css' const SelectedActions = ({count, size, unselect, remove, share, download, rename, inspect, className, ...props}) => { const text = (count > 1) ? 'Files selected' : 'File selected' + let singleFileAction = 'disabled o-50' + let singleFileTooltip = { + title: 'Only available for individual files' + } + + if (count === 1) { + singleFileAction = 'pointer' + singleFileTooltip = {} + } + return (
-
+
{count} @@ -31,18 +41,6 @@ const SelectedActions = ({count, size, unselect, remove, share, download, rename

Share

- { count === 1 && -
- -

Inspect IPLD

-
- } - { count === 1 && -
- -

Rename

-
- }

Download

@@ -51,9 +49,17 @@ const SelectedActions = ({count, size, unselect, remove, share, download, rename

Delete

+
+ +

Inspect IPLD

+
+
+ +

Rename

+
-
- +
+ Deselect all diff --git a/src/files/type-from-ext/extToType.js b/src/files/type-from-ext/extToType.js new file mode 100644 index 000000000..fdfc8b2ed --- /dev/null +++ b/src/files/type-from-ext/extToType.js @@ -0,0 +1,506 @@ +export default { + wav: 'audio', + bwf: 'audio', + aiff: 'audio', + flac: 'audio', + m4a: 'audio', + pac: 'audio', + tta: 'audio', + wv: 'audio', + aac: 'audio', + mp2: 'audio', + mp3: 'audio', + amr: 'audio', + s3m: 'audio', + '3gp': 'audio', + au: 'audio', + dct: 'audio', + dss: 'audio', + gsm: 'audio', + m4p: 'audio', + mmf: 'audio', + mpc: 'audio', + ogg: 'audio', + oga: 'audio', + opus: 'audio', + ra: 'audio', + sln: 'audio', + vox: 'audio', + '3g2': 'video', + aaf: 'video', + asf: 'video', + avchd: 'video', + avi: 'video', + drc: 'video', + flv: 'video', + m2v: 'video', + m4v: 'video', + mkv: 'video', + mng: 'video', + mov: 'video', + mp4: 'video', + mpe: 'video', + mpeg: 'video', + mpg: 'video', + mpv: 'video', + mxf: 'video', + nsv: 'video', + ogv: 'video', + qt: 'video', + rm: 'video', + rmvb: 'video', + roq: 'video', + svi: 'video', + vob: 'video', + webm: 'video', + wmv: 'video', + yuv: 'video', + art: 'image', + bmp: 'image', + blp: 'image', + cd5: 'image', + cit: 'image', + cpt: 'image', + cr2: 'image', + cut: 'image', + dds: 'image', + dib: 'image', + djvu: 'image', + egt: 'image', + exif: 'image', + gif: 'image', + gpl: 'image', + grf: 'image', + icns: 'image', + ico: 'image', + iff: 'image', + jng: 'image', + jpeg: 'image', + jpg: 'image', + jfif: 'image', + jp2: 'image', + jps: 'image', + lbm: 'image', + max: 'image', + miff: 'image', + msp: 'image', + nitf: 'image', + ota: 'image', + pbm: 'image', + pc1: 'image', + pc2: 'image', + pc3: 'image', + pcf: 'image', + pcx: 'image', + pdn: 'image', + pgm: 'image', + PI1: 'image', + PI2: 'image', + PI3: 'image', + pict: 'image', + pct: 'image', + pnm: 'image', + pns: 'image', + ppm: 'image', + psb: 'image', + psd: 'image', + pdd: 'image', + psp: 'image', + px: 'image', + pxm: 'image', + pxr: 'image', + qfx: 'image', + rle: 'image', + sct: 'image', + sgi: 'image', + rgb: 'image', + int: 'image', + bw: 'image', + tga: 'image', + tiff: 'image', + tif: 'image', + vtf: 'image', + xbm: 'image', + xcf: 'image', + xpm: 'image', + '3dv': 'image', + amf: 'image', + ai: 'image', + awg: 'image', + cgm: 'image', + cdr: 'image', + cmx: 'image', + dxf: 'image', + e2d: 'image', + eps: 'image', + fs: 'image', + gbr: 'image', + odg: 'image', + svg: 'image', + stl: 'image', + vrml: 'image', + x3d: 'image', + sxd: 'image', + v2d: 'image', + vnd: 'image', + wmf: 'image', + emf: 'image', + png: 'image', + webp: 'image', + jxr: 'image', + hdp: 'image', + wdp: 'image', + cur: 'image', + ecw: 'image', + liff: 'image', + nrrd: 'image', + pam: 'image', + pgf: 'image', + rgba: 'image', + inta: 'image', + sid: 'image', + ras: 'image', + sun: 'image', + '123': 'calc', + '12m': 'calc', + _xls: 'calc', + _xlsx: 'calc', + aws: 'calc', + bks: 'calc', + cell: 'calc', + def: 'calc', + dex: 'calc', + dfg: 'calc', + dis: 'calc', + edx: 'calc', + edxz: 'calc', + ess: 'calc', + fcs: 'calc', + fm: 'calc', + fods: 'calc', + fp: 'calc', + gnm: 'calc', + gnumeric: 'calc', + gsheet: 'calc', + hcdt: 'calc', + imp: 'calc', + mar: 'calc', + nb: 'calc', + ncss: 'calc', + nmbtemplate: 'calc', + numbers: 'calc', + 'numbers-tef': 'calc', + ods: 'calc', + ogw: 'calc', + ogwu: 'calc', + ots: 'calc', + pmd: 'calc', + pmdx: 'calc', + pmv: 'calc', + pmvx: 'calc', + qpw: 'calc', + rdf: 'calc', + sdc: 'calc', + stc: 'calc', + sxc: 'calc', + tmv: 'calc', + tmvt: 'calc', + uos: 'calc', + wki: 'calc', + wkq: 'calc', + wks: 'calc', + wku: 'calc', + wq1: 'calc', + wq2: 'calc', + xl: 'calc', + xlr: 'calc', + xls: 'calc', + xlsb: 'calc', + xlshtml: 'calc', + xlsm: 'calc', + xlsmhtml: 'calc', + xlsx: 'calc', + xlthtml: 'calc', + xltm: 'calc', + xltx: 'calc', + '1st': 'text', + _doc: 'text', + _docx: 'text', + abw: 'text', + adoc: 'text', + aim: 'text', + ans: 'text', + apkg: 'text', + apt: 'text', + asc: 'text', + ascii: 'text', + aty: 'text', + awp: 'text', + awt: 'text', + aww: 'text', + bad: 'text', + bbs: 'text', + bdp: 'text', + bdr: 'text', + bean: 'text', + bib: 'text', + bibtex: 'text', + bml: 'text', + bna: 'text', + boc: 'text', + brx: 'text', + btd: 'text', + bzabw: 'text', + calca: 'text', + charset: 'text', + chart: 'text', + chord: 'text', + cnm: 'text', + cod: 'text', + crwl: 'text', + cws: 'text', + cyi: 'text', + dca: 'text', + dfti: 'text', + dgs: 'text', + diz: 'text', + dne: 'text', + doc: 'text', + docm: 'text', + docx: 'text', + docxml: 'text', + docz: 'text', + dox: 'text', + dropbox: 'text', + dsc: 'text', + dvi: 'text', + dwd: 'text', + dx: 'text', + dxb: 'text', + dxp: 'text', + eio: 'text', + eit: 'text', + eml: 'text', + emlx: 'text', + emulecollection: 'text', + epp: 'text', + err: 'text', + etf: 'text', + etx: 'text', + euc: 'text', + 'fadein.template': 'text', + faq: 'text', + fbl: 'text', + fcf: 'text', + fdf: 'text', + fdr: 'text', + fds: 'text', + fdt: 'text', + fdx: 'text', + fdxt: 'text', + fft: 'text', + fgs: 'text', + flr: 'text', + fodt: 'text', + fountain: 'text', + fpt: 'text', + frt: 'text', + fwd: 'text', + fwdn: 'text', + gmd: 'text', + gpd: 'text', + gpn: 'text', + gsd: 'text', + gthr: 'text', + gv: 'text', + hbk: 'text', + hht: 'text', + hs: 'text', + hwp: 'text', + hz: 'text', + idx: 'text', + iil: 'text', + ipf: 'text', + ipspot: 'text', + jarvis: 'text', + jis: 'text', + jnp: 'text', + joe: 'text', + jp1: 'text', + jrtf: 'text', + jtd: 'text', + kes: 'text', + klg: 'text', + knt: 'text', + kon: 'text', + kwd: 'text', + latex: 'text', + lbt: 'text', + lis: 'text', + lnt: 'text', + log: 'text', + lp2: 'text', + lst: 'text', + ltr: 'text', + ltx: 'text', + lue: 'text', + luf: 'text', + lwp: 'text', + lxfml: 'text', + lyt: 'text', + lyx: 'text', + man: 'text', + mbox: 'text', + mcw: 'text', + 'md5.txt': 'text', + me: 'text', + mell: 'text', + mellel: 'text', + min: 'text', + mnt: 'text', + msg: 'text', + mw: 'text', + mwd: 'text', + mwp: 'text', + ndoc: 'text', + nfo: 'text', + ngloss: 'text', + njx: 'text', + note: 'text', + notes: 'text', + now: 'text', + nwctxt: 'text', + nwm: 'text', + nwp: 'text', + ocr: 'text', + odif: 'text', + odm: 'text', + odo: 'text', + odt: 'text', + ofl: 'text', + opeico: 'text', + openbsd: 'text', + ort: 'text', + ott: 'text', + p7s: 'text', + pages: 'text', + 'pages-tef': 'text', + pdpcmd: 'text', + pfx: 'text', + pjt: 'text', + plain: 'text', + plantuml: 'text', + pmo: 'text', + prt: 'text', + psw: 'text', + pu: 'text', + pvj: 'text', + pvm: 'text', + pwd: 'text', + pwdp: 'text', + pwdpl: 'text', + pwi: 'text', + pwr: 'text', + qdl: 'text', + qpf: 'text', + rad: 'text', + readme: 'text', + rft: 'text', + ris: 'text', + rpt: 'text', + rst: 'text', + rtd: 'text', + rtf: 'text', + rtfd: 'text', + rtx: 'text', + run: 'text', + rvf: 'text', + rzk: 'text', + rzn: 'text', + saf: 'text', + safetext: 'text', + sam: 'text', + save: 'text', + scc: 'text', + scm: 'text', + scriv: 'text', + scrivx: 'text', + scw: 'text', + sdm: 'text', + sdoc: 'text', + sdw: 'text', + se: 'text', + session: 'text', + sgm: 'text', + sig: 'text', + skcard: 'text', + sla: 'text', + 'sla.gz': 'text', + smf: 'text', + sms: 'text', + ssa: 'text', + story: 'text', + strings: 'text', + stw: 'text', + sty: 'text', + 'sublime-project': 'text', + 'sublime-workspace': 'text', + sxg: 'text', + sxw: 'text', + tab: 'text', + tdf: 'text', + template: 'text', + tex: 'text', + text: 'text', + textclipping: 'text', + thp: 'text', + tlb: 'text', + tm: 'text', + tmd: 'text', + tmdx: 'text', + tmvx: 'text', + tpc: 'text', + trelby: 'text', + tvj: 'text', + txt: 'text', + u3i: 'text', + unauth: 'text', + unx: 'text', + uof: 'text', + uot: 'text', + upd: 'text', + utf8: 'text', + utxt: 'text', + vct: 'text', + vnt: 'text', + vw: 'text', + wbk: 'text', + webdoc: 'text', + wn: 'text', + wp: 'text', + wp4: 'text', + wp5: 'text', + wp6: 'text', + wp7: 'text', + wpa: 'text', + wpd: 'text', + wpl: 'text', + wps: 'text', + wpt: 'text', + wpw: 'text', + wri: 'text', + wsd: 'text', + wtt: 'text', + wtx: 'text', + xbdoc: 'text', + xbplate: 'text', + xdl: 'text', + xwp: 'text', + xy: 'text', + xy3: 'text', + xyp: 'text', + xyw: 'text', + zabw: 'text', + zrtf: 'text', + zw: 'text' +} diff --git a/src/files/type-from-ext/index.js b/src/files/type-from-ext/index.js new file mode 100644 index 000000000..1ab4f4405 --- /dev/null +++ b/src/files/type-from-ext/index.js @@ -0,0 +1,7 @@ +import fileExtension from 'file-extension' +import extToType from './extToType' + +export default function (filename) { + const ext = fileExtension(filename) + return extToType[ext] || ext +} diff --git a/src/lib/path.js b/src/lib/path.js index 8c2d890ef..de2fc4355 100644 --- a/src/lib/path.js +++ b/src/lib/path.js @@ -17,3 +17,9 @@ export function quickSplitPath (str) { address: res[0] // /ipfs/QmHash/foo/bar } } + +export function join (a, b) { + if (a.endsWith('/')) a = a.slice(0, -1) + if (b.startsWith('/')) b = b.slice(1) + return `${a}/${b}` +} diff --git a/src/navigation/NavBar.js b/src/navigation/NavBar.js index 346ab2495..f9889cfb1 100644 --- a/src/navigation/NavBar.js +++ b/src/navigation/NavBar.js @@ -43,7 +43,7 @@ export default () => (