IntegerMan/angularIF

View on GitHub
src/app/app.component.ts

Summary

Maintainability
A
0 mins
Test Coverage
import {AfterViewChecked, Component, ElementRef, OnDestroy, OnInit, ViewChild} from '@angular/core';
import {InteractiveFictionService} from './engine/interactive-fiction.service';
import {Story} from './engine/entities/story';
import {CloakStory} from './stories/cloak-of-darkness/cloak-story';
import {CommonVerbService} from './engine/verbs/common-verb.service';
import {NavigationService} from './engine/navigation.service';
import {LoggingService} from './utility/logging.service';
import {TextLine} from './text-rendering/text-line';
import {TextOutputService} from './engine/text-output.service';
import {Subscription} from 'rxjs/Subscription';
import {GameState} from './engine/game-state.enum';

@Component({
  selector: 'if-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy, AfterViewChecked {

  lines: TextLine[] = [];
  title: string;
  stateClass: string = 'bg-warning';
  icon: string = 'fa-book';

  @ViewChild('scrollMe') private scrollContainer: ElementRef;

  private gameStateSubscription: Subscription;
  private linesChangedSubscription: Subscription;
  private respondToNextViewChecked: boolean = true;
  private gameState: GameState = GameState.initializing;

  constructor(private outputService: TextOutputService,
              private logger: LoggingService,
              private ifService: InteractiveFictionService,
              private navService: NavigationService,
              private verbService: CommonVerbService) {

    const story: Story = new CloakStory(navService);

    // Import the common set of verbs
    for (const verb of this.verbService.getCommonVerbs()) {
      story.verbHandlers.push(verb);
    }

    ifService.initialize(story);

    this.title = story.title;
    this.icon = story.fontAwesomeIcon;
  }

  ngOnInit() {
    this.lines = this.outputService.lines;
    this.gameStateSubscription = this.ifService.gameStateChanged.subscribe((s) => this.onGameStateChanged(s));
    this.linesChangedSubscription = this.outputService.linesChanged.subscribe(() => this.onLinesChanged());
    this.scrollToBottom();
    this.onGameStateChanged(this.ifService.gameState);
  }

  ngOnDestroy(): void {

    if (this.linesChangedSubscription) {
      this.linesChangedSubscription.unsubscribe();
    }

    if (this.gameStateSubscription) {
      this.gameStateSubscription.unsubscribe();
    }

  }

  ngAfterViewChecked(): void {

    if (this.respondToNextViewChecked) {
      this.respondToNextViewChecked = false;
      this.scrollToBottom();
    }

  }

  scrollToBottom(): void {
    try {
      LoggingService.instance.log('Scrolling to bottom');

      this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight;
    } catch (err) {
      LoggingService.instance.error(err);
    }
  }

  private onLinesChanged(): void {
    this.respondToNextViewChecked = true;
  }

  private onGameStateChanged(state: GameState): void {

    LoggingService.instance.debug(`Game state is now ${state}`);

    this.gameState = state;

    switch (state) {
      case GameState.underway:
        this.stateClass = 'bg-primary';
        break;

      case GameState.won:
        this.stateClass = 'bg-success';
        break;

      case GameState.lost:
        this.stateClass = 'bg-danger';
        break;

      default:
        this.stateClass = 'bg-warning';
        break;
    }
  }

}