diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index 7c9191d6..1f6e038b 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -54,7 +54,7 @@ jobs: - run: rm package.json pnpm-lock.yaml - name: Publish to Cloudflare Pages - if: "github.repository_owner == 'NuschtOS'" + if: github.event_name == 'push' uses: cloudflare/wrangler-action@v4 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} diff --git a/nix/frontend.nix b/nix/frontend.nix index c7bf7a87..f4c04a21 100644 --- a/nix/frontend.nix +++ b/nix/frontend.nix @@ -24,7 +24,7 @@ stdenv.mkDerivation (finalAttrs: { strictDeps = true; postPatch = '' - substituteInPlace src/index.html \ + substituteInPlace src/index.html public/opensearch-options.xml public/opensearch-packages.xml \ --replace-fail '##TITLE##' ${lib.escapeShellArg config.title} # remove development files diff --git a/package.json b/package.json index dd3c5a1d..fce4cf5f 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@angular/common": "^22.0.0", "@angular/compiler": "^22.0.0", "@angular/core": "^22.0.0", + "@angular/cdk": "^22.0.0", "@angular/forms": "^22.0.0", "@angular/platform-browser": "^22.0.0", "@angular/router": "^22.0.0", diff --git a/public/opensearch-options.xml b/public/opensearch-options.xml new file mode 100644 index 00000000..6e1b3335 --- /dev/null +++ b/public/opensearch-options.xml @@ -0,0 +1,8 @@ + + + ##TITLE## - Options + ##TITLE## options search + UTF-8 + favicon.ico + + diff --git a/public/opensearch-packages.xml b/public/opensearch-packages.xml new file mode 100644 index 00000000..c6b8dbea --- /dev/null +++ b/public/opensearch-packages.xml @@ -0,0 +1,8 @@ + + + ##TITLE## - Packages + ##TITLE## packages search + UTF-8 + favicon.ico + + diff --git a/src/app/core/opensearch-link.ts b/src/app/core/opensearch-link.ts new file mode 100644 index 00000000..815571b5 --- /dev/null +++ b/src/app/core/opensearch-link.ts @@ -0,0 +1,18 @@ +import { CONFIG } from './config.domain'; + +export type OpenSearchType = 'options' | 'packages'; + +export function setOpenSearchLink(document: Document, type: OpenSearchType): void { + const existing = document.head.querySelector('link[data-nuschtos-opensearch]'); + const link = existing ?? document.head.appendChild(document.createElement('link')); + + link.rel = 'search'; + link.type = 'application/opensearchdescription+xml'; + link.dataset['nuschtosOpensearch'] = 'true'; + link.title = `${CONFIG.title} ${type === 'options' ? 'Options' : 'Packages'} Search`; + link.href = `${CONFIG.baseHref}opensearch-${type}.xml`; +} + +export function clearOpenSearchLink(document: Document): void { + document.head.querySelector('link[data-nuschtos-opensearch]')?.remove(); +} diff --git a/src/app/pages/options/options-page.component.ts b/src/app/pages/options/options-page.component.ts index d7931074..0c821ed8 100644 --- a/src/app/pages/options/options-page.component.ts +++ b/src/app/pages/options/options-page.component.ts @@ -1,11 +1,12 @@ import { ChangeDetectionStrategy, Component, Inject, LOCALE_ID, OnDestroy } from '@angular/core'; -import { CONFIG } from '../../core/config.domain'; +import { DOCUMENT } from '@angular/common'; import { OptionComponent } from '../../core/components/option/option.component'; import { OptionsService } from '../../core/data/options.service'; import { OptionsSearchComponent } from '../../core/components/search/search.component'; import { RouterLink } from '@angular/router'; -import { AsyncPipe, DecimalPipe, formatNumber } from '@angular/common'; +import { AsyncPipe, formatNumber } from '@angular/common'; import { BehaviorSubject, Subject, takeUntil } from 'rxjs'; +import { clearOpenSearchLink, setOpenSearchLink } from '../../core/opensearch-link'; @Component({ selector: 'app-options', @@ -27,8 +28,10 @@ export class OptionsPageComponent implements OnDestroy { constructor( protected readonly searchService: OptionsService, + @Inject(DOCUMENT) private readonly document: Document, @Inject(LOCALE_ID) private readonly locale: string ) { + setOpenSearchLink(this.document, 'options'); this.searchService.getIndexSize() .pipe(takeUntil(this.destroy$)) .subscribe(size => { @@ -36,6 +39,7 @@ export class OptionsPageComponent implements OnDestroy { }); } ngOnDestroy(): void { + clearOpenSearchLink(this.document); this.destroy$.next(); this.destroy$.complete(); } diff --git a/src/app/pages/packages/packages-page.component.ts b/src/app/pages/packages/packages-page.component.ts index 92a7008e..b00cba3c 100644 --- a/src/app/pages/packages/packages-page.component.ts +++ b/src/app/pages/packages/packages-page.component.ts @@ -1,9 +1,11 @@ import { ChangeDetectionStrategy, Component, Inject, LOCALE_ID, OnDestroy } from '@angular/core'; +import { DOCUMENT } from '@angular/common'; import { PackagesSearchComponent } from '../../core/components/search/search.component'; import { PackagesService } from '../../core/data/packages.service'; import { PackageComponent } from "../../core/components/package/package.component"; import { AsyncPipe, formatNumber } from '@angular/common'; import { BehaviorSubject, Subject, takeUntil } from 'rxjs'; +import { clearOpenSearchLink, setOpenSearchLink } from '../../core/opensearch-link'; @Component({ selector: 'app-packages-page.component', @@ -23,8 +25,10 @@ export class PackagesPageComponent implements OnDestroy { constructor( protected readonly searchService: PackagesService, + @Inject(DOCUMENT) private readonly document: Document, @Inject(LOCALE_ID) private readonly locale: string ) { + setOpenSearchLink(this.document, 'packages'); this.searchService.getIndexSize() .pipe(takeUntil(this.destroy$)) .subscribe(size => { @@ -32,6 +36,7 @@ export class PackagesPageComponent implements OnDestroy { }); } ngOnDestroy(): void { + clearOpenSearchLink(this.document); this.destroy$.next(); this.destroy$.complete(); }