-
- {{#each this.blocks as |row|}}
-
- {{#each row.blocks as |block|}}
- {{#let (this.blockify block) as |BlockComponent|}}
- {{#if BlockComponent}}
- {{component
- BlockComponent
- size=block.size
- period=block.period
- }}
- {{/if}}
- {{/let}}
- {{/each}}
-
- {{/each}}
+
+
+
+ {{#each this.blocks as |row|}}
+
+ {{#each row.blocks as |block|}}
+ {{#let (this.blockify block) as |BlockComponent|}}
+ {{#if BlockComponent}}
+ {{component
+ BlockComponent
+ size=block.size
+ period=block.period
+ }}
+ {{/if}}
+ {{/let}}
+ {{/each}}
+
+ {{/each}}
+
-
+
}
diff --git a/javascripts/discourse/connectors/discovery-navigation-bar-above/navigation.gjs b/javascripts/discourse/connectors/discovery-navigation-bar-above/navigation.gjs
index de43d88..adc3bbd 100644
--- a/javascripts/discourse/connectors/discovery-navigation-bar-above/navigation.gjs
+++ b/javascripts/discourse/connectors/discovery-navigation-bar-above/navigation.gjs
@@ -1,34 +1,186 @@
import Component from "@glimmer/component";
-// import { tracked } from "@glimmer/tracking";
-// import { concat, get } from "@ember/helper";
-// import { action } from "@ember/object";
+import { tracked } from "@glimmer/tracking";
+import { on } from "@ember/modifier";
+import { action } from "@ember/object";
import { service } from "@ember/service";
-// import { htmlSafe } from "@ember/template";
-// import { eq, or } from "truth-helpers";
-// import avatar from "discourse/helpers/avatar";
-// import categoryLink from "discourse/helpers/category-link";
-// import concatClass from "discourse/helpers/concat-class";
-// import number from "discourse/helpers/number";
-// import replaceEmoji from "discourse/helpers/replace-emoji";
-// import { ajax } from "discourse/lib/ajax";
-// import Category from "discourse/models/category";
+import { capitalize } from "@ember/string";
+import { eq } from "truth-helpers";
import i18n from "discourse-common/helpers/i18n";
export default class Breadcrumbs extends Component {
@service router;
@service site;
+ @tracked routeType;
+
+ @action
+ updateRouteType() {
+ if (this.router?.currentRoute?.parent?.name === "discovery") {
+ switch (this.router?.currentRoute?.localName) {
+ case "latest":
+ case "hot":
+ case "top":
+ case "new":
+ case "unread":
+ this.routeType = "home";
+ break;
+ case "category":
+ case "latestCategory":
+ case "hotCategory":
+ case "topCategory":
+ case "newCategory":
+ case "unreadCategory":
+ this.routeType = "category";
+ break;
+ case "categories":
+ this.routeType = "categories";
+ break;
+ default:
+ this.routeType = null;
+ break;
+ }
+ } else {
+ this.routeType = null;
+ }
+ }
+
+ get filterType() {
+ if (this.router?.currentRoute?.localName === "categories") {
+ return "categories";
+ }
+ return this.router?.currentRoute?.attributes?.filterType || "";
+ }
+
get isHomepage() {
- return this.router.currentRouteName === "discovery.latest";
+ this.updateRouteType();
+ return this.routeType === "home";
+ }
+
+ get isCategoryView() {
+ this.updateRouteType();
+ return this.routeType === "category";
+ }
+
+ get isCategoryList() {
+ this.updateRouteType();
+ return this.routeType === "categories";
+ }
+
+ get categoryName() {
+ return this.router?.currentRoute?.attributes?.category?.name || "Category";
+ }
+
+ get categoryBadge() {
+ const defaultBadge = settings.default_category_badge || "📁";
+
+ const badge = settings.category_icons?.find(
+ (category) =>
+ category.id[0] === this.router?.currentRoute?.attributes?.category?.id
+ )?.emoji;
+
+ if (!badge) {
+ return defaultBadge;
+ }
+
+ try {
+ // check for valid emoji
+ const regex = /\p{Emoji}/u;
+ if (regex.test(badge)) {
+ return badge;
+ }
+ return defaultBadge;
+ } catch (e) {
+ // \p{Emoji} not supported -> skip validation
+ return badge;
+ }
+ }
+
+ @action
+ home() {
+ this.router.transitionTo("/");
}
{{#if this.isHomepage}}
-
+
+
+ home
+
{{i18n "js.home"}}
+ {{else if this.isCategoryView}}
+
+
+ {{this.categoryBadge}}
+
+ {{this.categoryName}}
+
+ {{else if this.isCategoryList}}
+
+
+ 🗃️
+
+ {{capitalize (i18n "js.categories.categories_label")}}
+
{{/if}}
+
}
+class TopicFilter extends Component {
+ @service router;
+ @service site;
+
+ @tracked filterOptions;
+
+ constructor() {
+ super(...arguments);
+
+ this.filterOptions =
+ this.site.siteSettings?.top_menu?.split("|").map((item) => {
+ return { name: item, localization: `js.filters.${item}.title` };
+ }) || [];
+ }
+
+ @action
+ filterTopics(event) {
+ const routeType = this.args.routeType;
+ const category = this.router?.currentRoute?.attributes?.category;
+
+ if (routeType === "category" && event.target.value !== "categories") {
+ this.router.transitionTo(
+ `/c/${category.slug}/${category.id}/l/${event.target.value}`
+ );
+ } else {
+ this.router.transitionTo(`/${event.target.value}`);
+ }
+ }
+
+
+
+
+}
diff --git a/javascripts/discourse/connectors/topic-title/back.hbs b/javascripts/discourse/connectors/topic-title/back.hbs
new file mode 100644
index 0000000..67827d7
--- /dev/null
+++ b/javascripts/discourse/connectors/topic-title/back.hbs
@@ -0,0 +1,4 @@
+{{#unless this.model.isPrivateMessage}}
+
+
+{{/unless}}
\ No newline at end of file
diff --git a/javascripts/discourse/modifiers/scroll.js b/javascripts/discourse/modifiers/scroll.js
new file mode 100644
index 0000000..09a8c22
--- /dev/null
+++ b/javascripts/discourse/modifiers/scroll.js
@@ -0,0 +1,11 @@
+import { modifier } from 'ember-modifier';
+
+export default modifier((element, [callback]) => {
+ const handleScroll = () => callback();
+
+ window.addEventListener('scroll', handleScroll);
+
+ return () => {
+ window.removeEventListener('scroll', handleScroll);
+ };
+});
diff --git a/scss/components/navigation.scss b/scss/components/navigation.scss
index cfa571a..de83a1e 100644
--- a/scss/components/navigation.scss
+++ b/scss/components/navigation.scss
@@ -326,6 +326,7 @@
height: 4.5rem;
border-bottom: var(--border-outer);
+ padding: 0 1rem;
&__title {
@include headline-small;
@@ -335,12 +336,34 @@
align-items: center;
margin: 0;
- padding: 0 1rem;
-
- &::before {
- @include i;
+ .badge {
+ &[data-badge-type="icon"]{
+ @include i;
+ }
+ &[data-badge-type="emoji"]{
+ width: 1.25rem;
+ line-height: 1;
+ font-size: 1.25rem;
+ }
+ &[data-clickable="true"]{
+ cursor: pointer;
+ }
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 24px;
padding: 0 0.375rem;
}
}
+ &__select {
+ width: auto;
+ max-width: 180px;
+
+ margin-left: auto;
+ margin-bottom: 0;
+
+ border: none;
+ padding: 0 3px;
+ }
}
diff --git a/scss/discourse/topic.scss b/scss/discourse/topic.scss
index 657715b..a836068 100644
--- a/scss/discourse/topic.scss
+++ b/scss/discourse/topic.scss
@@ -1,4 +1,5 @@
#topic-title {
+ display: flex;
border-bottom: var(--border-outer);
padding: 1rem;
margin: 0;
@@ -9,6 +10,18 @@
color: var(--neutral-10);
}
}
+ .topic-title-outlet {
+ padding-top: 8px;
+ order: -1;
+ .topic-back-button {
+ &:before {
+ @include i;
+ padding-left: 12px;
+ padding-right: 16px;
+ content: "arrow_back";
+ }
+ }
+ }
}
.more-topics__container .nav {
@@ -187,4 +200,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/scss/layout.scss b/scss/layout.scss
index 63b3e05..99dfa63 100644
--- a/scss/layout.scss
+++ b/scss/layout.scss
@@ -91,6 +91,10 @@ body {
padding-left: 0;
}
+ .sticky-sidebar {
+ display: unset;
+ }
+
.blocks {
grid-area: right;
}
diff --git a/settings.yml b/settings.yml
index 004ee1d..ddafa38 100644
--- a/settings.yml
+++ b/settings.yml
@@ -122,3 +122,21 @@ blocks:
default: 1x1
period:
type: null
+category_badges:
+ type: objects
+ default: []
+ schema:
+ name: category_badge
+ properties:
+ category:
+ type: categories
+ required: true
+ badge:
+ type: string
+ description: a single emoji to use as a badge (copy and paste from https://emojipedia.org/twitter)
+ max_length: 1
+ required: true
+default_category_icon:
+ default: 📁
+ description: a single emoji to use as a default category icon (copy and paste from https://emojipedia.org/twitter)
+ max: 1
\ No newline at end of file