diff --git a/assets/javascripts/discourse/components/activity-pub-nav-item.hbs b/assets/javascripts/discourse/components/activity-pub-nav-item.hbs index 2c6a654e..e0ef051c 100644 --- a/assets/javascripts/discourse/components/activity-pub-nav-item.hbs +++ b/assets/javascripts/discourse/components/activity-pub-nav-item.hbs @@ -1,17 +1,12 @@ -{{#if @model}} - - {{d-icon "discourse-activity-pub"}} - {{i18n "discourse_activity_pub.discovery.label"}} - -{{/if}} \ No newline at end of file + + {{d-icon "discourse-activity-pub"}} + {{i18n "discourse_activity_pub.discovery.label"}} + \ No newline at end of file diff --git a/assets/javascripts/discourse/components/activity-pub-nav-item.js b/assets/javascripts/discourse/components/activity-pub-nav-item.js index 4e028346..871fe915 100644 --- a/assets/javascripts/discourse/components/activity-pub-nav-item.js +++ b/assets/javascripts/discourse/components/activity-pub-nav-item.js @@ -3,6 +3,7 @@ import { tracked } from "@glimmer/tracking"; import { inject as service } from "@ember/service"; import getURL from "discourse-common/lib/get-url"; import { bind } from "discourse-common/utils/decorators"; +import I18n from "I18n"; import ActivityPubActor, { actorClientPath, actorModels, @@ -14,28 +15,50 @@ export default class ActivityPubNavItem extends Component { @service site; @service currentUser; - @tracked visible; + @tracked visible = false; @tracked actor; + @tracked model; @bind - subscribe() { + setup() { this.messageBus.subscribe("/activity-pub", this.handleActivityPubMessage); + this.changeCategory(); + this.changeTag(); } @bind - unsubscribe() { + teardown() { this.messageBus.unsubscribe("/activity-pub", this.handleActivityPubMessage); } @bind - didChangeModel() { - const actor = ActivityPubActor.findByModel( - this.args.model, - this.args.modelType - ); + changeCategory() { + if (this.args.category) { + this.model = this.args.category; + this.modelType = "category"; + this.modelName = this.model.name; + this.changeModel(); + } + } + + @bind + changeTag() { + if (this.args.tag) { + this.model = this.args.tag; + this.modelType = "tag"; + this.modelName = this.model.id; + this.changeModel(); + } + } + + changeModel() { + const actor = ActivityPubActor.findByModel(this.model, this.modelType); if (actor && this.canAccess(actor)) { this.actor = actor; this.visible = true; + } else { + this.actor = null; + this.visible = false; } } @@ -47,8 +70,8 @@ export default class ActivityPubNavItem extends Component { handleActivityPubMessage(data) { if ( actorModels.includes(data.model.type) && - this.args.model && - data.model.id.toString() === this.args.model.id.toString() + this.model && + data.model.id.toString() === this.model.id.toString() ) { this.visible = data.model.ready; } @@ -75,6 +98,15 @@ export default class ActivityPubNavItem extends Component { return getURL(`${actorClientPath}/${this.actor.id}/${path}`); } + get title() { + if (!this.model) { + return ""; + } + return I18n.t("discourse_activity_pub.discovery.description", { + model_name: this.modelName, + }); + } + get active() { return this.router.currentRouteName.includes(`activityPub.actor`); } diff --git a/assets/javascripts/discourse/connectors/extra-nav-item/activity-pub-navigation.hbs b/assets/javascripts/discourse/connectors/extra-nav-item/activity-pub-navigation.hbs index b2fa4a8b..e492f1c8 100644 --- a/assets/javascripts/discourse/connectors/extra-nav-item/activity-pub-navigation.hbs +++ b/assets/javascripts/discourse/connectors/extra-nav-item/activity-pub-navigation.hbs @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/javascripts/discourse/connectors/extra-nav-item/activity-pub-navigation.js b/assets/javascripts/discourse/connectors/extra-nav-item/activity-pub-navigation.js index 89617516..ad801d45 100644 --- a/assets/javascripts/discourse/connectors/extra-nav-item/activity-pub-navigation.js +++ b/assets/javascripts/discourse/connectors/extra-nav-item/activity-pub-navigation.js @@ -2,21 +2,4 @@ export default { shouldRender(attrs, ctx) { return ctx.site.activity_pub_enabled; }, - - setupComponent(attrs, component) { - let model; - let modelType; - if (attrs.category) { - model = attrs.category; - modelType = "category"; - } - if (attrs.tag) { - model = attrs.tag; - modelType = "tag"; - } - component.setProperties({ - model, - modelType, - }); - }, }; diff --git a/test/javascripts/acceptance/activity-pub-discovery-test.js b/test/javascripts/acceptance/activity-pub-discovery-test.js index a9e670d9..69d97e94 100644 --- a/test/javascripts/acceptance/activity-pub-discovery-test.js +++ b/test/javascripts/acceptance/activity-pub-discovery-test.js @@ -7,6 +7,7 @@ import { exists, query, } from "discourse/tests/helpers/qunit-helpers"; +import selectKit from "discourse/tests/helpers/select-kit-helper"; import I18n from "I18n"; import { default as Actors } from "../fixtures/actors-fixtures"; import { default as Followers } from "../fixtures/followers-fixtures"; @@ -74,6 +75,35 @@ acceptance( server.get(`${followersPath}.json`, () => helper.response(Followers[followersPath]) ); + server.get("/tag/:tag_name/notifications", (request) => { + return helper.response({ + tag_notification: { + id: request.params.tag_name, + notification_level: 1, + }, + }); + }); + server.get("/tag/:tag_name/l/latest.json", (request) => { + return helper.response({ + users: [], + primary_groups: [], + topic_list: { + can_create_topic: true, + draft: null, + draft_key: "new_topic", + draft_sequence: 1, + per_page: 30, + tags: [ + { + id: 1, + name: request.params.tag_name, + topic_count: 1, + }, + ], + topics: [], + }, + }); + }); }); test("with a non-category route", async function (assert) { @@ -133,6 +163,50 @@ acceptance( "shows the right category banner tip" ); }); + + test("when routing from a category with an actor to one without", async function (assert) { + const category = Category.findById(2); + Site.current().set("activity_pub_actors", SiteActors); + + await visit(category.url); + + assert.ok( + exists(".activity-pub-route-nav.visible"), + "the activitypub nav button is visible" + ); + + const categoryDrop = selectKit(".category-drop"); + await categoryDrop.expand(); + await categoryDrop.selectRowByValue(7); + + assert.ok( + !exists(".activity-pub-route-nav.visible"), + "the activitypub nav button is not visible" + ); + }); + + test("when routing from a tag with an actor to one without", async function (assert) { + Site.current().setProperties({ + activity_pub_actors: SiteActors, + top_tags: ["monkey", "dog"], + }); + + await visit("/tag/monkey"); + + assert.ok( + exists(".activity-pub-route-nav.visible"), + "the activitypub nav button is visible" + ); + + const tagDrop = selectKit(".tag-drop"); + await tagDrop.expand(); + await tagDrop.selectRowByName("dog"); + + assert.ok( + !exists(".activity-pub-route-nav.visible"), + "the activitypub nav button is not visible" + ); + }); } ); diff --git a/test/javascripts/components/activity-pub-status-test.js b/test/javascripts/components/activity-pub-status-test.js index f6b337e7..3bb7813b 100644 --- a/test/javascripts/components/activity-pub-status-test.js +++ b/test/javascripts/components/activity-pub-status-test.js @@ -32,7 +32,7 @@ function setCategory(context) { function setTag(context) { const store = getOwner(context).lookup("service:store"); - const tag = store.createRecord("tag", { id: 1, name: "tag_1" }); + const tag = store.createRecord("tag", { id: 1, name: "monkey" }); context.set("tag", tag); } diff --git a/test/javascripts/fixtures/site-actors-fixtures.js b/test/javascripts/fixtures/site-actors-fixtures.js index dd7fc6d9..47761a9f 100644 --- a/test/javascripts/fixtures/site-actors-fixtures.js +++ b/test/javascripts/fixtures/site-actors-fixtures.js @@ -46,12 +46,12 @@ export default { tag: [ { id: 4, - handle: "@tag1@test.local", - name: "Tag 1", - username: "tag_1", + handle: "@monkey@test.local", + name: "Monkey", + username: "monkey", model_type: "Tag", model_id: 1, - model_name: "tag_1", + model_name: "monkey", can_admin: true, default_visibility: "public", publication_type: "first_post",