os-js / osjs-client

OS.js Client Module
https://manual.os-js.org/
Other
31 stars 31 forks source link

Emit Event on VFS Resolve/Reject #124

Closed josephjeno closed 4 years ago

josephjeno commented 4 years ago

Currently an event is emitted when VFS methods are called, however it would also be nice to emit something when the request has finished.

This would be very useful for displaying some sort of loading indicator to the user during a file upload/download.

andersevenrud commented 4 years ago

I just pushed a new release that emits an event when the Promise is settled. These events are suffixed with :done.

Here's a basic example on how it could be used:

class VFSLoadingIndicatorService extends ServiceProvider {
  init() {
    const trays = {};
    const theme = this.core.make('osjs/theme');

    const remove = (file) => {
      const entry = trays[file.path];
      if (entry) {
        entry.destroy();
        delete trays[file.path];
      }
    };

    this.core.on('osjs/vfs:readfile', (file) => {
      remove(file);

      trays[file.path] = this.core.make('osjs/tray', {
        title: `Downloading ${file.filename}`,
        icon: theme.icon('emblem-downloads')
      });
    });

    this.core.on('osjs/vfs:readfile:done', remove);
  }

  depends() {
    return [
      'osjs/tray'
    ];
  }
}
josephjeno commented 4 years ago

This is really awesome! Thank you!

andersevenrud commented 4 years ago

No problem. Any time!

andersevenrud commented 4 years ago

I realize my example was a bit wonk, so here's a better one :)

class VFSLoadingIndicatorService {
  constructor(core) {
    this.core = core;
    this.entries = new Map();
  }

  destroy() {
    this.entries.forEach(entry => entry.destroy());
    this.entries.clear();
  }

  init() {
    this.core.on('osjs/vfs:readfile', file => this.announce(file));
    this.core.on('osjs/vfs:readfile:done', file => this.denounce(file));
  }

  depends() {
    return [
      'osjs/tray'
    ];
  }

  announce(file) {
    if (!this.entries.has(file.path)) {
      const theme = this.core.make('osjs/theme');
      const entry = this.core.make('osjs/tray', {
        title: `Downloading ${file.filename}`,
        icon: theme.icon('emblem-downloads')
      });

      this.entries.set(file.path, entry);
    }
  }

  denounce(file) {
    const entry = this.entries.get(file.path);
    if (entry) {
      entry.destroy();
      this.entries.delete(file.path);
    }
  }
}