Showing different content for mobile view in a .gjs file

Trying to update our custom theme component to the new standard after the deprecation notice and I can’t figure out how to show different stuff for mobile users in this setting.

The theme guide doesn’t mention anything about this, the only relevant post I found is api.renderInOutlet not rendering? - #3 by NateDhaliwal which uses this.site.mobileView so I assumed something like the following should work:

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer("1.8.0", (api) => {
  api.renderInOutlet(
    "composer-after-save-or-cancel",
    <template>
      {{#if this.site.mobileView}}
      Mobile!
      {{else}}
      Normal!
      {{/if}}
    </template>
  );
});

But I only ever see the normal content… I am obviously missing something basic…

Thanks for any hints!

Oh, it probably just needs to import the site service manually.

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer("1.8.0", (api) => {
  const site = api.container.lookup("service:site");
  api.renderInOutlet(
    "composer-after-save-or-cancel",
    <template>
      {{#if site.mobileView}}
      Mobile!
      {{else}}
      Normal!
      {{/if}}
    </template>
  );
});
3 Likes

Would @service site; work also?

No. The @service decorator is only available in Ember classes like Components or Services. If the <template>...</template> was refactored as a separate component, then you can use the decorator. As the apiInitializer() is only a function, the service has to be accessed like normal JS.

You can see Ember object ownership (getOwner, service injections, etc.)

1 Like

If you like, you can put an entire class inside the renderInOutlet call:

import { apiInitializer } from "discourse/lib/api";
import Component from "@glimmer/component";
import { service } from "@ember/service";

export default apiInitializer((api) => {
  api.renderInOutlet(
    "composer-after-save-or-cancel",
    class extends Component {
      @service site;

      <template>
        {{#if this.site.mobileView}}
          Mobile!
        {{else}}
          Normal!
        {{/if}}
      </template>
    }
  );
});

But the .lookup() solution is also reasonable - that’s what @service is doing behind-the-scenes anyway :ok_hand:

6 Likes

Thanks, this works!

Also funny how (at lest this flavor of) modern JS increasingly looks like enterprise Java when I used to work in that world (early 2010s) :smiley: