From e335e7c92bc27c45570919f8cbc8bca0b37b32b7 Mon Sep 17 00:00:00 2001 From: Ricardo Gobbo de Souza Date: Wed, 3 Jun 2020 18:56:30 -0300 Subject: [PATCH] feat: progress bar --- lib/module.js | 4 +++ lib/plugin.js | 80 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/lib/module.js b/lib/module.js index e769d62..61ece7c 100755 --- a/lib/module.js +++ b/lib/module.js @@ -45,6 +45,7 @@ function httpModule (_moduleOptions) { const options = { baseURL: `http://${defaultHost}:${defaultPort}${prefix}`, browserBaseURL: undefined, + progress: true, proxyHeaders: true, proxyHeadersIgnore: ['accept', 'host', 'cf-ray', 'cf-connecting-ip', 'content-length'], proxy: false, @@ -101,6 +102,9 @@ function httpModule (_moduleOptions) { options.browserBaseURL = https(options.browserBaseURL) } + // globalName + options.globalName = this.nuxt.options.globalName || 'nuxt' + // Register plugin this.addPlugin({ src: path.resolve(__dirname, 'plugin.js'), diff --git a/lib/plugin.js b/lib/plugin.js index 715c7f7..77eac06 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -51,10 +51,14 @@ class HTTP { this._hook('onError', fn) } + onDownloadProgress(fn) { + this._defaults.onDownloadProgress = fn + } + create(options) { const { retry, timeout, prefixUrl, headers } = this._defaults - return new HTTP(defu(options, { retry, timeout, prefixUrl, headers })) + return createHttpInstance(defu(options, { retry, timeout, prefixUrl, headers })) } } @@ -104,6 +108,77 @@ for (let method of ['get', 'head', 'delete', 'post', 'put', 'patch']) { } } +const createHttpInstance = options => { + // Create new HTTP instance + const http = new HTTP(options) + + // Setup interceptors + <% if (options.progress) { %>setupProgress(http) <% } %> + + return http +} + +<% if (options.progress) { %> +const setupProgress = (http) => { + if (process.server) { + return + } + + // A noop loading inteterface for when $nuxt is not yet ready + const noopLoading = { + finish: () => { }, + start: () => { }, + fail: () => { }, + set: () => { } + } + + const $loading = () => { + const $nuxt = typeof window !== 'undefined' && window['$<%= options.globalName %>'] + return ($nuxt && $nuxt.$loading && $nuxt.$loading.set) ? $nuxt.$loading : noopLoading + } + + let currentRequests = 0 + + http.onRequest(config => { + if (config && config.progress === false) { + return + } + + currentRequests++ + }) + + http.onResponse(response => { + if (response && response.config && response.config.progress === false) { + return + } + + currentRequests-- + if (currentRequests <= 0) { + currentRequests = 0 + $loading().finish() + } + }) + + http.onError(error => { + if (error && error.config && error.config.progress === false) { + return + } + + currentRequests-- + + $loading().fail() + $loading().finish() + }) + + http.onDownloadProgress(e => { + if (!currentRequests) { + return + } + const progress = ((e.transferredBytes * 100) / (e.totalBytes * currentRequests)) + $loading().set(Math.min(100, progress)) + }) +}<% } %> + export default (ctx, inject) => { // prefixUrl const prefixUrl = process.browser @@ -136,8 +211,7 @@ export default (ctx, inject) => { defaults.headers['accept-encoding'] = 'gzip, deflate' } - // Create new HTTP instance - const http = new HTTP(defaults) + const http = createHttpInstance(defaults) // Inject http to the context as $http ctx.$http = http