Adding a poll button to the bottom of the composer

This is actually tricker than it seems (how hard can it be to move a button right? :slight_smile: )

I had a brief tackle of this and it seems the least messy way is assign the composer editor toolbar to a controller property you can then access in the outlet.

If you try to recreate the behaviour of the toolbar, you run into the immediate issues @spirobel mentioned, but will probably run into other issues down the line as the text parsing logic is tweaked.

The basic principle being to try and use the functionality at the highest level of abstrction, i.e. we need the toolbar of the actual composer editor…so let’s get that.

i.e.

api.modifyClass("component:d-editor", {
  @on('didInsertElement')
  makeToolbarAccessible() {
    if (this.outletArgs && this.outletArgs.editorType === 'composer') {
      const controller = getOwner(this).lookup('controller:composer');
      controller.set('editorToolbar', this.toolbar);
    }
  }
});

Then in the outlet we get the toolbar from the composer controller and add a new button to it. There may be a way to use the existing poll button (that would be ideal), but it’s in wrapped up in the popupMenu logic, and I couldn’t see a way to extricate it.

setupComponent(attrs, ctx) {
  const controller = getOwner(this).lookup('controller:composer');
  
  controller.addObserver('editorToolbar', function() {
    if (this._state === 'destroying') return;

    const toolbar = controller.editorToolbar;
          
    toolbar.addButton({
      group: "extras",
      icon: "chart-bar",
      title: "poll.ui_builder.title",
      sendAction: e => {
        controller.send('storeToolbarState', e);
        this.send("showPollBuilder");
      }
    });
    
    const extras = toolbar.groups.find(g => g.group == 'extras');
    const pollButton = extras.buttons.find(b => b.icon == "chart-bar");
        
    ctx.set('pb', pollButton);
  });
}

Then in the template itself

{{d-button
  type="button"
  action=pb.action
  actionParam=pb
  translatedTitle=pb.title
  icon=pb.icon
  class=pb.className}}

@nexo Give this theme component a whirl: discourse-poll-button-bottom.zip (2.5 KB)

p.s. I just loaded it on thepavilion.io and it seems to be working (mobile only).

4 Likes