Angular Konami Service

Michael Richins - Feb 24 - - Dev Community

Do you want the perfect easter egg for you website?

I have used this on several websites of mine. At the last company I worked for, I could use it and choose a user. Their webpage would then be mirrored for 5 minutes. It was a small company and it got a lot of laughs. I have used it to toggle development mode, show/hide settings, or even pair this with and Angular Can Activate Guard and disallow routes that haven't had the code put in.

Service

import { isPlatformBrowser } from '@angular/common';
import {
  EventEmitter,
  inject,
  Injectable,
  Output,
  PLATFORM_ID,
} from '@angular/core';

@Injectable({ providedIn: 'root' })
export class KonamiService {
  #inputSequence: Array<string> = [];
  #konamiCode: Array<string> = [
    'ArrowUp',
    'ArrowUp',
    'ArrowDown',
    'ArrowDown',
    'ArrowLeft',
    'ArrowRight',
    'ArrowLeft',
    'ArrowRight',
    'b',
    'a',
  ];
  #platformId: {} = inject(PLATFORM_ID);
  #successful: boolean = false;

  get successful(): boolean {
    return this.#successful;
  }

  @Output() konamiCodeActivated = new EventEmitter<void>();

  constructor() {
    this.initialize();
  }

  initialize() {
    if (isPlatformBrowser(this.#platformId)) {
      this.#addWindowKeydownHandler();
    }
  }

  destroy() {
    this.#removeWindowKeydownHandler();
  }

  #addWindowKeydownHandler() {
    window.addEventListener(
      'keydown',
      this.#handleWindowKeydownEvent.bind(this)
    );
  }

  #removeWindowKeydownHandler() {
    window.removeEventListener(
      'keydown',
      this.#handleWindowKeydownEvent.bind(this)
    );
  }

  #handleWindowKeydownEvent(event: KeyboardEvent) {
    this.#inputSequence.push(event.key);

    if (this.#inputSequence.length > this.#konamiCode.length) {
      this.#inputSequence.shift();
    }

    const inputArray = this.#inputSequence.join(',');
    const konamiArray = this.#konamiCode.join(',');

    if (inputArray === konamiArray) {
      this.konamiCodeActivated.emit();
      this.#inputSequence = [];
      this.#successful = true;
    } else {
      this.#successful = false;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Guard (Optional)

import { KonamiService } from '$shared/services/konami.service';
import { inject, Injectable } from '@angular/core';
import { CanActivate, GuardResult, MaybeAsync } from '@angular/router';
import { map, take } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class KonamiGuard implements CanActivate {
  #konamiService: KonamiService = inject(KonamiService);

  canActivate(): MaybeAsync<GuardResult> {
    if (this.#konamiService.successful) {
      return true;
    } else {
      return false;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Use

import { Component, inject, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { KonamiService } from '$shared/services/konami.service';

@Component({
  selector: 'app-home-route',
  templateUrl: 'home.page.html',
  styleUrl: 'home.page.scss',
})
export class HomePage implements OnInit, OnDestroy {
  #konamiService: KonamiService = inject(KonamiService);
  #subs: Array<Subscription> = [];

  ngOnInit() {
    this.#subs = [
      ...this.#subs,
      this.#konamiService.konamiCodeActivated.subscribe(() => {
        // DO SOMETHING HERE
      }),
    ];
  }

  ngOnDestroy() {
    this.#subs.forEach((sub) => sub.unsubscribe);
  }
}
Enter fullscreen mode Exit fullscreen mode
.