From 87fbe45f855f760d51a9a5c1a3f740ec39c91e93 Mon Sep 17 00:00:00 2001 From: Kris Date: Wed, 3 May 2023 12:51:27 -0400 Subject: [PATCH] FEATURE: integration with category banners (#9) --- .github/workflows/component-linting.yml | 48 ------ .github/workflows/component-tests.yml | 147 ------------------ .github/workflows/discourse-theme.yml | 11 ++ common/common.scss | 32 ++++ .../discourse-tag-banners-presentation.hbs | 23 +++ .../discourse-tag-banners-presentation.js | 5 + .../discourse-tag-banners-text-only.hbs | 10 ++ .../discourse-tag-banners-text-only.js | 5 + .../components/discourse-tag-banners.hbs | 37 ++--- .../components/discourse-tag-banners.js | 11 ++ .../above-site-header/tag-header-widget.hbs | 4 +- .../above-site-header/tag-header-widget.js | 16 ++ .../below-site-header/tag-header-widget.hbs | 4 +- .../below-site-header/tag-header-widget.js | 16 ++ .../category-banner-tag-connector.hbs | 1 + 15 files changed, 152 insertions(+), 218 deletions(-) delete mode 100644 .github/workflows/component-linting.yml delete mode 100644 .github/workflows/component-tests.yml create mode 100644 .github/workflows/discourse-theme.yml create mode 100644 javascripts/discourse/components/discourse-tag-banners-presentation.hbs create mode 100644 javascripts/discourse/components/discourse-tag-banners-presentation.js create mode 100644 javascripts/discourse/components/discourse-tag-banners-text-only.hbs create mode 100644 javascripts/discourse/components/discourse-tag-banners-text-only.js create mode 100644 javascripts/discourse/connectors/above-site-header/tag-header-widget.js create mode 100644 javascripts/discourse/connectors/below-site-header/tag-header-widget.js create mode 100644 javascripts/discourse/connectors/category-banners-after-title/category-banner-tag-connector.hbs diff --git a/.github/workflows/component-linting.yml b/.github/workflows/component-linting.yml deleted file mode 100644 index 2385132..0000000 --- a/.github/workflows/component-linting.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: Linting - -on: - push: - branches: - - main - pull_request: - -concurrency: - group: plugin-linting-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: 16 - cache: yarn - - - name: Yarn install - run: yarn install - - - name: ESLint - if: ${{ always() }} - run: yarn eslint --ext .js,.js.es6 --no-error-on-unmatched-pattern {test,javascripts} - - - name: Prettier - if: ${{ always() }} - shell: bash - run: | - yarn prettier -v - files=$(find javascripts desktop mobile common scss -type f \( -name "*.scss" -or -name "*.js" -or -name "*.es6" \) 2> /dev/null) || true - if [ -n "$files" ]; then - yarn prettier --list-different $files - fi - if [ 0 -lt $(find test -type f \( -name "*.js" -or -name "*.es6" \) 2> /dev/null | wc -l) ]; then - yarn prettier --list-different "test/**/*.{js,es6}" - fi - - - name: Ember template lint - if: ${{ always() }} - run: yarn ember-template-lint --no-error-on-unmatched-pattern javascripts diff --git a/.github/workflows/component-tests.yml b/.github/workflows/component-tests.yml deleted file mode 100644 index 944aa1e..0000000 --- a/.github/workflows/component-tests.yml +++ /dev/null @@ -1,147 +0,0 @@ -name: Tests - -on: - push: - branches: - - main - pull_request: - -concurrency: - group: plugin-tests-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }} - cancel-in-progress: true - -jobs: - check: - runs-on: ubuntu-latest - outputs: - tests_exist: ${{ steps.check_tests.outputs.tests_exist }} - - steps: - - name: Install component - uses: actions/checkout@v3 - with: - path: tmp/component - fetch-depth: 1 - - - name: Check QUnit existence - id: check_tests - shell: bash - run: | - if [ 0 -lt $(find tmp/component/test -type f \( -name "*.js" -or -name "*.es6" \) 2> /dev/null | wc -l) ]; then - echo "::set-output name=tests_exist::true" - fi - - test: - needs: check - if: ${{ needs.check.outputs.tests_exist }} - runs-on: ubuntu-latest - container: discourse/discourse_test:slim-browsers - timeout-minutes: 15 - - env: - DISCOURSE_HOSTNAME: www.example.com - RUBY_GLOBAL_METHOD_CACHE_SIZE: 131072 - RAILS_ENV: development - PGUSER: discourse - PGPASSWORD: discourse - - steps: - - uses: actions/checkout@v3 - with: - repository: discourse/discourse - fetch-depth: 1 - - - name: Install component - uses: actions/checkout@v3 - with: - path: tmp/component - fetch-depth: 1 - - - name: Setup Git - run: | - git config --global user.email "ci@ci.invalid" - git config --global user.name "Discourse CI" - - - name: Start redis - run: | - redis-server /etc/redis/redis.conf & - - - name: Start Postgres - run: | - chown -R postgres /var/run/postgresql - sudo -E -u postgres script/start_test_db.rb - sudo -u postgres psql -c "CREATE ROLE $PGUSER LOGIN SUPERUSER PASSWORD '$PGPASSWORD';" - - - name: Bundler cache - uses: actions/cache@v3 - with: - path: vendor/bundle - key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }} - restore-keys: | - ${{ runner.os }}-gem- - - - name: Setup gems - run: | - gem install bundler --conservative -v $(awk '/BUNDLED WITH/ { getline; gsub(/ /,""); print $0 }' Gemfile.lock) - bundle config --local path vendor/bundle - bundle config --local deployment true - bundle config --local without development - bundle install --jobs 4 - bundle clean - - - name: Lint English locale - run: bundle exec ruby script/i18n_lint.rb "tmp/component/locales/en.yml" - - - name: Get yarn cache directory - id: yarn-cache-dir - run: echo "::set-output name=dir::$(yarn cache dir)" - - - name: Yarn cache - uses: actions/cache@v3 - id: yarn-cache - with: - path: ${{ steps.yarn-cache-dir.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - - name: Yarn install - run: yarn install - - - name: Fetch app state cache - uses: actions/cache@v3 - id: app-cache - with: - path: tmp/app-cache - key: >- - ${{ hashFiles('.github/workflows/tests.yml') }}- - ${{ hashFiles('db/**/*', 'plugins/**/db/**/*') }}- - - - name: Restore database from cache - if: steps.app-cache.outputs.cache-hit == 'true' - run: psql -f tmp/app-cache/cache.sql postgres - - - name: Restore uploads from cache - if: steps.app-cache.outputs.cache-hit == 'true' - run: rm -rf public/uploads && cp -r tmp/app-cache/uploads public/uploads - - - name: Create and migrate database - if: steps.app-cache.outputs.cache-hit != 'true' - run: | - bin/rake db:create - bin/rake db:migrate - - - name: Dump database for cache - if: steps.app-cache.outputs.cache-hit != 'true' - run: mkdir -p tmp/app-cache && pg_dumpall > tmp/app-cache/cache.sql - - - name: Dump uploads for cache - if: steps.app-cache.outputs.cache-hit != 'true' - run: rm -rf tmp/app-cache/uploads && cp -r public/uploads tmp/app-cache/uploads - - - name: Component QUnit - run: | - THEME_NAME=$(ruby -e 'require "json"; puts JSON.parse(File.read("tmp/component/about.json"))["name"]') - bundle exec rake themes:install -- "--{\"$THEME_NAME\": \"tmp/component\"}" - UNICORN_TIMEOUT=120 bundle exec rake "themes:qunit[name,$THEME_NAME]" - timeout-minutes: 10 diff --git a/.github/workflows/discourse-theme.yml b/.github/workflows/discourse-theme.yml new file mode 100644 index 0000000..8adaaec --- /dev/null +++ b/.github/workflows/discourse-theme.yml @@ -0,0 +1,11 @@ +name: Discourse Theme + +on: + push: + branches: + - main + pull_request: + +jobs: + ci: + uses: discourse/.github/.github/workflows/discourse-theme.yml@v1 diff --git a/common/common.scss b/common/common.scss index cd8e6d6..28dbd75 100644 --- a/common/common.scss +++ b/common/common.scss @@ -47,3 +47,35 @@ } } } + +// category banner integration + +.tag-banner__text-only { + display: flex; + align-items: center; + justify-content: center; + font-size: var(--font-down-4); + font-weight: normal; + + .d-icon { + font-size: var(--font-down-3); + margin-right: 0.33em; + } + + .discourse-tag, + .discourse-tag.bullet, + .discourse-tag.box, + .discourse-tag.simple { + margin: 0; + color: currentColor; + &:before { + background: currentColor; + } + } + + .discourse-tag.box { + background: transparent; + font-size: var(--font-down-1); + box-shadow: 0 0 0 1px currentColor; + } +} diff --git a/javascripts/discourse/components/discourse-tag-banners-presentation.hbs b/javascripts/discourse/components/discourse-tag-banners-presentation.hbs new file mode 100644 index 0000000..ba281b4 --- /dev/null +++ b/javascripts/discourse/components/discourse-tag-banners-presentation.hbs @@ -0,0 +1,23 @@ +
+
+

+ {{@formattedTagName}} + {{#if @formattedAdditionalTagNames}} + & + {{@formattedAdditionalTagNames}} + {{/if}} +

+ {{#unless @isIntersection}} + {{! hide descriptions on tag intersections}} + {{#if (theme-setting "show_tag_description")}} +

{{@tag.description}}

+ {{/if}} + {{/unless}} +
+
diff --git a/javascripts/discourse/components/discourse-tag-banners-presentation.js b/javascripts/discourse/components/discourse-tag-banners-presentation.js new file mode 100644 index 0000000..7894162 --- /dev/null +++ b/javascripts/discourse/components/discourse-tag-banners-presentation.js @@ -0,0 +1,5 @@ +import Component from "@ember/component"; + +export default class DiscourseTagBannersPresentation extends Component { + tagName = ""; // removing an extra tag that is added by default +} diff --git a/javascripts/discourse/components/discourse-tag-banners-text-only.hbs b/javascripts/discourse/components/discourse-tag-banners-text-only.hbs new file mode 100644 index 0000000..f679b64 --- /dev/null +++ b/javascripts/discourse/components/discourse-tag-banners-text-only.hbs @@ -0,0 +1,10 @@ +
+ {{#if (eq this.site.siteSettings.tag_style "simple")}} + {{d-icon "tag"}} + {{/if}} + {{discourse-tag @formattedTagName}} + {{#if @formattedAdditionalTagNames}} + & + {{@formattedAdditionalTagNames}} + {{/if}} +
diff --git a/javascripts/discourse/components/discourse-tag-banners-text-only.js b/javascripts/discourse/components/discourse-tag-banners-text-only.js new file mode 100644 index 0000000..c69e816 --- /dev/null +++ b/javascripts/discourse/components/discourse-tag-banners-text-only.js @@ -0,0 +1,5 @@ +import Component from "@ember/component"; + +export default class DiscourseTagBannersTextOnly extends Component { + tagName = ""; // removing an extra tag that is added by default +} diff --git a/javascripts/discourse/components/discourse-tag-banners.hbs b/javascripts/discourse/components/discourse-tag-banners.hbs index 1ae4157..9c0afb3 100644 --- a/javascripts/discourse/components/discourse-tag-banners.hbs +++ b/javascripts/discourse/components/discourse-tag-banners.hbs @@ -1,30 +1,25 @@ -{{#if (not (and this.site.mobileView (not (theme-setting "show_on_mobile"))))}} +{{#if (not (and this.site.mobileView (theme-setting "show_on_mobile")))}} {{#if this.shouldRender}}
-
-

- {{this.formattedTagName}} - {{#if this.formattedAdditionalTagNames}} - & - {{this.formattedAdditionalTagNames}} - {{/if}} -

- {{#unless this.isIntersection}} - {{! hide descriptions on tag intersections}} - {{#if (theme-setting "show_tag_description")}} -

{{this.tag.description}}

- {{/if}} - {{/unless}} -
+ {{#if this.categoryBannerPresence.isPresent}} + + {{else}} + + {{/if}}
{{/if}} {{/if}} diff --git a/javascripts/discourse/components/discourse-tag-banners.js b/javascripts/discourse/components/discourse-tag-banners.js index 02d0098..6068d98 100644 --- a/javascripts/discourse/components/discourse-tag-banners.js +++ b/javascripts/discourse/components/discourse-tag-banners.js @@ -2,15 +2,26 @@ import Component from "@glimmer/component"; import { tracked } from "@glimmer/tracking"; import { action } from "@ember/object"; import { inject as service } from "@ember/service"; +import { getOwner } from "discourse-common/lib/get-owner"; export default class DiscourseTagBanners extends Component { @service store; @service router; @service site; + @tracked categoryBannerPresence = null; @tracked tag = null; @tracked keepDuringLoadingRoute = false; @tracked isIntersection = false; + constructor() { + super(...arguments); + + // this prevents a failure if the category banner component is not installed + this.categoryBannerPresence = getOwner(this).lookup( + "service:categoryBannerPresence" + ); + } + #formatTagName(tagName = "") { // for intersections: tag1/tag2 => tag1 & tag2 tagName = tagName.replace(/\//g, " & "); diff --git a/javascripts/discourse/connectors/above-site-header/tag-header-widget.hbs b/javascripts/discourse/connectors/above-site-header/tag-header-widget.hbs index ba4d93c..a5afc90 100644 --- a/javascripts/discourse/connectors/above-site-header/tag-header-widget.hbs +++ b/javascripts/discourse/connectors/above-site-header/tag-header-widget.hbs @@ -1,3 +1,5 @@ {{#if (theme-setting "show_above_site_header")}} - + {{#unless this.categoryBannerPresence.isPresent}} + + {{/unless}} {{/if}} diff --git a/javascripts/discourse/connectors/above-site-header/tag-header-widget.js b/javascripts/discourse/connectors/above-site-header/tag-header-widget.js new file mode 100644 index 0000000..92d19f5 --- /dev/null +++ b/javascripts/discourse/connectors/above-site-header/tag-header-widget.js @@ -0,0 +1,16 @@ +import Component from "@ember/component"; +import { tracked } from "@glimmer/tracking"; +import { getOwner } from "discourse-common/lib/get-owner"; + +export default class extends Component { + @tracked categoryBannerPresence = null; + + constructor() { + super(...arguments); + + // this prevents a failure if the category banner component is not installed + this.categoryBannerPresence = getOwner(this).lookup( + "service:categoryBannerPresence" + ); + } +} diff --git a/javascripts/discourse/connectors/below-site-header/tag-header-widget.hbs b/javascripts/discourse/connectors/below-site-header/tag-header-widget.hbs index 7fd736f..4e30ea1 100644 --- a/javascripts/discourse/connectors/below-site-header/tag-header-widget.hbs +++ b/javascripts/discourse/connectors/below-site-header/tag-header-widget.hbs @@ -1,3 +1,5 @@ {{#if (theme-setting "show_below_site_header")}} - + {{#unless this.categoryBannerPresence.isPresent}} + + {{/unless}} {{/if}} diff --git a/javascripts/discourse/connectors/below-site-header/tag-header-widget.js b/javascripts/discourse/connectors/below-site-header/tag-header-widget.js new file mode 100644 index 0000000..92d19f5 --- /dev/null +++ b/javascripts/discourse/connectors/below-site-header/tag-header-widget.js @@ -0,0 +1,16 @@ +import Component from "@ember/component"; +import { tracked } from "@glimmer/tracking"; +import { getOwner } from "discourse-common/lib/get-owner"; + +export default class extends Component { + @tracked categoryBannerPresence = null; + + constructor() { + super(...arguments); + + // this prevents a failure if the category banner component is not installed + this.categoryBannerPresence = getOwner(this).lookup( + "service:categoryBannerPresence" + ); + } +} diff --git a/javascripts/discourse/connectors/category-banners-after-title/category-banner-tag-connector.hbs b/javascripts/discourse/connectors/category-banners-after-title/category-banner-tag-connector.hbs new file mode 100644 index 0000000..8372cd9 --- /dev/null +++ b/javascripts/discourse/connectors/category-banners-after-title/category-banner-tag-connector.hbs @@ -0,0 +1 @@ +