Making ‘previous/next topic’ keyboard shortcuts into a theme component

I’d like to make these previous-next topic button keyboard shortcuts into a theme component that provides << Prev Topic and Next Topic >> buttons in the header.

Can anyone suggest an existing theme component with a code snippet that provides a button that simply activates an existing keyboard shortcut?

I’m starting with

1 Like

This kind of already exists (but focusses on Next).

This uses the Core API so should continue to work …

PR accepted if you want to add a back button option with setting.

4 Likes

Thank you, @merefield! I am stuck (at least I think that’s where :nerd_face: ) at the javascript snippet for the back button…

discourse-tc-topic-next-button/javascripts/discourse/components/topic-previous-button.js at master · denvergeeks/discourse-tc-topic-next-button · GitHub where at the moment I have this…

import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import {
  nextTopicUrl,
  previousTopicUrl,
} from "discourse/lib/topic-list-tracker";
import DiscourseURL from "discourse/lib/url";
import { inject as service } from "@ember/service";

export default class TopicPreviousButton extends Component {
  @service site;
  @tracked label = "";
  @tracked showButton = false;
  @tracked lastURL = "";

  constructor(owner, args) {
    super(owner, args);
    previousTopicUrl().then((url) => {
      if (url) {
        this.showButton = true;
        this.lastURL = url;
      } else {
        this.showButton = false;
        this.lastURL = "";
      }
    })
  };

  get goFirst() {
    return settings.topic_next_always_go_to_first_post
  }

  @action
  goToPreviousTopic() {
    let url;
    if (this.lastURL) {
      url = this.goFirst
        ? this.lastURL.substring(0, this.lastURL.nextIndexOf("/"))
        : this.lastURL;
      DiscourseURL.routeTo(url);
    }
  };
}

I think the problem is near the bottom at

? this.lastURL.substring(0, this.lastURL.nextIndexOf("/"))

Any thoughts?

I tried

? this.lastURL.substring(0, this.lastURL.indexOf("/"))

You probably don’t want to create a separate component for the back button and handle all of the logic in the same component. Just extend the existing template and js file as needed. Otherwise you will likely end up with three templates instead of one which would seem excessive for such a small “component”?

Hmm… not sure what you are seeing in my code, but I’m just adding code to your existing component :grinning:

Yeah we are using a different definition of Component here in dev :slight_smile:

This is a different Glimmer Component.

So one Theme Component containing one Glimmer Component. You were about to create an extra one?

I suggest you edit the same file, which will need two actions not one. And perhaps the label can only appear if the back button is not activated in the new setting?

Thanks Robert – I think I understand. I’ll give this a go.

1 Like