guess-the-year-web-component 3.0.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "guess-the-year-web-component",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "Guess the year",
5
5
  "main": "dist/main.js",
6
6
  "type": "module",
@@ -9,13 +9,12 @@
9
9
  "customElements": "custom-elements.json",
10
10
  "scripts": {
11
11
  "test": "echo \"Error: no test specified\" && exit 1",
12
- "copy:assets": "cp -r src/assets dist",
13
12
  "build:dev": "rimraf dist && webpack --mode=development",
14
13
  "build:prod": "rimraf dist && npm run build:module && npm run build:package",
15
- "build:module": "tsc && npm run copy:assets",
14
+ "build:module": "tsc",
16
15
  "build:package": "webpack --mode=production --node-env=production",
17
16
  "watch": "webpack --watch",
18
- "develop": "npm run copy:assets && cross-env webpack serve --hot --mode development --port 8000",
17
+ "develop": "cross-env webpack serve --hot --mode development --port 8000",
19
18
  "dev": "npm run develop",
20
19
  "serve": "webpack serve",
21
20
  "lint": "npm run lint:lit-analyzer && npm run lint:eslint",
@@ -1,29 +1,18 @@
1
1
  import { LitElement, css, html, PropertyValues, TemplateResult } from "lit";
2
2
  import { customElement, property, state } from "lit/decorators.js";
3
- import { unsafeHTML } from "lit/directives/unsafe-html.js";
4
- // import { Task } from '@lit/task';
5
3
  import dayjs from "dayjs";
6
4
  import { Dayjs } from "dayjs";
7
-
8
5
  const { setTimeout } = window;
9
-
10
- import { Incident, Categories } from "./lib/Incident";
11
- import { NoImageImg, RefreshIconSVG, SolutionIconSVG } from "./lib/Icon";
6
+ import { Incident, Categories, Category } from "./lib/Incident";
7
+ import { NoImageImg } from "./lib/Icon";
12
8
  import { ApiService, ContentFeedback } from "./lib/ApiService";
13
9
  import { Util } from "./lib/Util";
14
10
  import { i18nFactory } from "./lib/i18n/i18n";
15
-
16
11
  import { GameState } from "./lib/enums";
17
-
18
12
  import stylesheet from "./scss/main.scss";
19
-
20
13
  import { QuestionScoreController } from "./lib/controller/scorecontroller";
21
14
 
22
- // const GREEN = "#07d207";
23
- // const RED = "#ec3737";
24
- // const BLACK = "#000";
25
-
26
- const SPLASH_DELAY: number = 3000;
15
+ const SPLASH_DELAY: number = 1000;
27
16
  const MIN_YEAR: number = 1950;
28
17
  const MAX_YEAR: number = 2024;
29
18
  const MAX_QUESTIONS: number = 10;
@@ -31,9 +20,6 @@ const HINT_COST: number = 2;
31
20
 
32
21
  @customElement("guess-the-year")
33
22
  export class GuessTheYear extends LitElement {
34
- private _startTime: Date = new Date();
35
- private _endTime: Date = new Date();
36
- // private _uuid = Math.random();
37
23
  private sources: Array<string> = [];
38
24
  private _loading = false;
39
25
 
@@ -72,7 +58,7 @@ export class GuessTheYear extends LitElement {
72
58
  type: Dayjs,
73
59
  converter: {
74
60
  fromAttribute: (value: string) => {
75
- console.info(["from", "from", value]);
61
+ console.debug(["from", "from", value]);
76
62
  if (!value) {
77
63
  return dayjs();
78
64
  }
@@ -84,7 +70,7 @@ export class GuessTheYear extends LitElement {
84
70
  return dayjs(`${value}-01-01`, "YYYY-MM-DD");
85
71
  },
86
72
  toAttribute: (value: Dayjs) => {
87
- console.info(["from", "to", value]);
73
+ console.debug(["from", "to", value]);
88
74
  return value.format("YYYY-MM-DD");
89
75
  },
90
76
  },
@@ -95,7 +81,7 @@ export class GuessTheYear extends LitElement {
95
81
  type: Dayjs,
96
82
  converter: {
97
83
  fromAttribute: (value: string) => {
98
- console.info(["to", "from", value]);
84
+ console.debug(["to", "from", value]);
99
85
  if (!value) {
100
86
  return dayjs();
101
87
  }
@@ -107,43 +93,22 @@ export class GuessTheYear extends LitElement {
107
93
  return dayjs(`${value}-12-31`, "YYYY-MM-DD");
108
94
  },
109
95
  toAttribute: (value: Dayjs) => {
110
- console.info(["to", "to", value]);
96
+ console.debug(["to", "to", value]);
111
97
  return value.format("YYYY-MM-DD");
112
98
  },
113
99
  },
114
100
  })
115
101
  to: Dayjs = dayjs(); // defaults to today
116
102
 
117
- @property({ type: String })
118
- limit: string = "";
119
-
120
- @property({ type: Boolean })
121
- shuffle: boolean = false;
122
-
123
- @property({ type: Boolean, attribute: "show-duration" })
124
- showDuration: boolean = false;
125
-
126
- @property({ type: Boolean, attribute: "show-feedback" })
127
- showFeedback: boolean = false;
128
-
129
103
  @property({ type: String, attribute: "no-image-src" })
130
104
  noImageSrc: string = "";
131
105
 
132
106
  @property({ type: Boolean, attribute: "suppress-images" })
133
107
  suppressImages: boolean = false;
134
108
 
135
- @property({ type: Boolean, attribute: "auto-focus" })
136
- autoFocus: boolean = false;
137
-
138
- @property({ type: Number, attribute: "hint-interval-length" })
139
- hintIntervalSecs: number = 7;
140
-
141
109
  @property({ type: Number, attribute: "max-hints" })
142
110
  maxHints: number = 3;
143
111
 
144
- @property({ type: Number, attribute: "max-tries" })
145
- maxTries: number = -1;
146
-
147
112
  @property({ type: Number, attribute: "number-of-questions", reflect: true })
148
113
  numberOfQuestions: number = 10;
149
114
  private _numberOfQuestionsSeen: number = 0;
@@ -164,15 +129,6 @@ export class GuessTheYear extends LitElement {
164
129
  @state()
165
130
  private _solution: Number | undefined = undefined;
166
131
 
167
- @state()
168
- private _displaySolution: boolean = false;
169
-
170
- @state()
171
- private _answeredCorrectly: boolean = false;
172
-
173
- @state()
174
- private _tries: number = 0;
175
-
176
132
  @state()
177
133
  public _renderState: string = GameState.INIT;
178
134
 
@@ -186,21 +142,15 @@ export class GuessTheYear extends LitElement {
186
142
  private _answer: number | undefined = undefined;
187
143
 
188
144
  private _apiService = new ApiService(this.teeeApiUrl);
189
- private _intervalsPassed: number = 0;
190
145
  private i18n = i18nFactory("nl");
191
146
 
192
147
  static override styles = css`
193
148
  ${stylesheet}
194
149
  `;
195
150
 
196
- // private _game_engine: Engine;
197
-
198
151
  constructor() {
199
152
  super();
200
-
201
153
  this._score0 = new QuestionScoreController(this, 30, 1000);
202
-
203
- // this._engine = new GameController(this);
204
154
  }
205
155
 
206
156
  override connectedCallback() {
@@ -214,7 +164,6 @@ export class GuessTheYear extends LitElement {
214
164
  override disconnectedCallback() {
215
165
  console.debug("disconnectedCallback");
216
166
  super.disconnectedCallback();
217
- // clearInterval(this._intervalHandler);
218
167
  this._renderState = GameState.INIT;
219
168
  this._score0.stop();
220
169
  this._score0.reset();
@@ -301,10 +250,6 @@ export class GuessTheYear extends LitElement {
301
250
  return html`
302
251
  <div id="splash-screen-container" class="splashscreen">
303
252
  <div class="splash-logo">
304
- <img
305
- src="./assets/logo.png"
306
- alt="logo"
307
- />
308
253
  <h2>${this.i18n.translate("game-name")}</h2>
309
254
  <p>${this.i18n.translate("Loading...")}</p>
310
255
  </div>
@@ -332,9 +277,8 @@ export class GuessTheYear extends LitElement {
332
277
  // allows to select the number of questions,
333
278
  // select the year range
334
279
  // and to start the game
335
- // TODO: add real content
336
280
  private renderGameIntro(): TemplateResult {
337
- console.info("renderGameIntro");
281
+ console.debug("renderGameIntro");
338
282
 
339
283
  // pre-render number of question options
340
284
  // and mark selected when they match
@@ -407,7 +351,7 @@ export class GuessTheYear extends LitElement {
407
351
  console.debug("renderGameStage");
408
352
 
409
353
  return html`
410
- ${this._renderHeader(this.i18n.translate("game-call-to-action"))}
354
+ ${this._renderHeader(this.i18n.translate("game-call-to-action").replace(/__FROM__/, this.from.year() + '').replace(/__TO__/, this.to.year() + ''))}
411
355
  <div class="guess-the-year-game-stage">
412
356
  <div class="game-score">${this._renderGameScore()}</div>
413
357
 
@@ -442,12 +386,23 @@ export class GuessTheYear extends LitElement {
442
386
  `;
443
387
  }
444
388
 
389
+ private _shouldDisplayAnImage(incident: Incident): boolean {
390
+ const hasImage = !!(incident && incident.image && incident.image[0]);
391
+ const displayImages = !this.suppressImages;
392
+ return hasImage && displayImages;
393
+ }
394
+
445
395
  // renders the optional image with the item
446
396
  private _renderIncidentImage(incident: Incident | undefined): TemplateResult {
447
- if (incident && incident.image) {
397
+ if (incident && this._shouldDisplayAnImage(incident)) {
448
398
  return html`
449
399
  <div class="incident--image">
450
- <img src="${incident.image}" />
400
+ <img
401
+ @error=${(evt: Event) => {
402
+ this._handleImageLoadError(evt, incident);
403
+ }}
404
+ src="${incident.image[0]}"
405
+ />
451
406
  </div>
452
407
  `;
453
408
  }
@@ -506,7 +461,7 @@ export class GuessTheYear extends LitElement {
506
461
  // check if the answer is correct
507
462
  if (answer) {
508
463
  // this._apiService.postIncidentAnswer(this._incident?.id, answer);
509
- console.info(
464
+ console.debug(
510
465
  answer,
511
466
  this._solution,
512
467
  this._score,
@@ -536,7 +491,7 @@ export class GuessTheYear extends LitElement {
536
491
  return html`
537
492
  <div class="game-controls--hint">
538
493
  <button @click="${this._handleHintClicked}">
539
- ${this.i18n.translate("show-hint")} (${this.maxHints - this._hintsIndex})
494
+ ${this.i18n.translate("show-hint")} (${this._hints.length - this._hintsIndex})
540
495
  </button>
541
496
  </div>
542
497
  `;
@@ -547,7 +502,7 @@ export class GuessTheYear extends LitElement {
547
502
  // subtracts the cost of the hint from
548
503
  // the question score
549
504
  private _handleHintClicked(): void {
550
- console.info("handleHintClicked", [this._hintsIndex, this._hints.length]);
505
+ console.debug("handleHintClicked", [this._hintsIndex, this._hints.length]);
551
506
 
552
507
  if (this._hintsIndex < this._hints.length) {
553
508
  const hintText = this._generateHintText(this._hints[this._hintsIndex]);
@@ -662,9 +617,9 @@ export class GuessTheYear extends LitElement {
662
617
  // private _totalScore: number = 0;
663
618
 
664
619
  private setupNewGame(): void {
665
- console.log("new game!");
620
+ console.debug("new game!");
666
621
 
667
- console.info({
622
+ console.debug({
668
623
  "number of questions": this.numberOfQuestions,
669
624
  from: this.from.toISOString(),
670
625
  to: this.to.toISOString(),
@@ -708,11 +663,8 @@ export class GuessTheYear extends LitElement {
708
663
  "quiz_year"
709
664
  );
710
665
 
711
- this._startTime = new Date();
712
- this._endTime = new Date();
713
666
  this._incident = response.incident;
714
667
  this.sources = response.sources;
715
- this._tries = this.maxTries;
716
668
 
717
669
  this._solution = Number(
718
670
  (response.incident?.yearplusmonth || "").substring(0, 4),
@@ -736,12 +688,12 @@ export class GuessTheYear extends LitElement {
736
688
  this._answers = answers;
737
689
 
738
690
  for (let i = 0; i < this.maxHints; i++) {
739
- console.info("loading hint", i);
691
+ console.debug("loading hint", i);
740
692
 
741
693
  const response: { incident: Incident | undefined; sources: string[] } =
742
694
  await this._apiService.fetchOneIncident(
743
695
  this.country,
744
- Util.shuffleArray(Categories).shift(),
696
+ Util.shuffleArray([...Categories]).shift(),
745
697
  undefined,
746
698
  undefined,
747
699
  "",
@@ -773,130 +725,16 @@ export class GuessTheYear extends LitElement {
773
725
  this._numberOfQuestionsSeen += 1;
774
726
  }
775
727
 
776
- renderRefreshButton(): TemplateResult {
777
- return html`<div class="refresh" id="refresh" @click="${this.setupNewGame}">
778
- <span>${unsafeHTML(RefreshIconSVG)}</span>
779
- </div>`;
780
- }
781
-
782
- renderStopGameButton(): TemplateResult {
783
- return html`<div
784
- class="stop-game"
785
- id="stop-game"
786
- @click="${() => {
787
- this._displaySolution = true;
788
- }}"
789
- >
790
- <span>${unsafeHTML(SolutionIconSVG)}</span>
791
- </div>`;
792
- }
793
-
794
- renderFeedbackPossibility(): TemplateResult {
795
- if (this.showFeedback) {
796
- return html`<div class="feedback-possibility">
797
- <input
798
- type="text"
799
- id="feedback"
800
- size="15"
801
- placeholder="${this.i18n.translate("your-feedback")}"
802
- />
803
- </div>`;
804
- } else {
805
- return html``;
806
- }
807
- }
808
-
809
- renderSubmitPossibility(): TemplateResult {
810
- return html`<div class="submit-possibility">
811
- <input
812
- type="text"
813
- id="answer"
814
- size="15"
815
- ?disabled=${this._displaySolution}
816
- placeholder="${this.i18n.translate("your-answer")}"
817
- />
818
- ${this.renderTries()}
819
- </div>`;
820
- }
821
-
822
- renderTries(): TemplateResult {
823
- const i18nKey = this._tries > 1 ? "tries-left" : "try-left";
824
- if (this._tries >= 0 && !this._displaySolution) {
825
- return html`<span class="tries"
826
- >${this.i18n
827
- .translate(i18nKey)
828
- .replace("__TRIES__", "" + this._tries)}</span
829
- >`;
830
- }
831
- return html``;
832
- }
833
-
834
- renderTheSolution(): TemplateResult {
835
- if (this._displaySolution) {
836
- return html`<div class="solution">${this._solution}</div>
837
- ${this.renderTheDuration()} `;
838
- }
839
- return html``;
840
- }
841
-
842
- renderTheDuration(): TemplateResult {
843
- const duration = Math.round(
844
- new Date(this._endTime.getTime() - this._startTime.getTime()).getTime() /
845
- 1000,
846
- );
847
- const i18nKey = duration === 1 ? "in-x-seconds" : "in-one-second";
848
- if (this.showDuration && this._answeredCorrectly) {
849
- return html`<div class="timer">
850
- ${this.i18n.translate(i18nKey).replace("__SECONDS__", "" + duration)}
851
- </div>`;
852
- }
853
- return html``;
854
- }
855
-
856
- renderTiles(incident: Incident | undefined) {
857
- console.debug("renderTiles");
858
- if (!incident) {
859
- return "";
860
- }
861
- return html`${this.renderTile(incident)}`;
862
- }
863
-
864
- private _tileShouldDisplayAnImage(incident: Incident): boolean {
865
- const hasImage = !!incident.image;
866
- const displayImages = !this.suppressImages;
867
- return hasImage && displayImages;
868
- }
869
-
870
- renderTile(incident: Incident): TemplateResult {
871
- console.debug("renderTile");
872
- const tileContent: TemplateResult = this.renderTileContent(incident);
873
- if (this._tileShouldDisplayAnImage(incident)) {
874
- return html`<div class="guess-the-year-tile with-image">
875
- ${tileContent}
876
- </div>`;
877
- }
878
-
879
- return html`<div class="guess-the-year-tile">${tileContent}</div>`;
880
- }
881
-
882
- renderTileContent(incident: Incident): TemplateResult {
883
- console.debug("renderTileContent");
884
- return html`<div class="guess-the-year-tile-content">
885
- ${this.renderTileTitle(incident)} ${this.renderTileImage(incident)}
886
- ${this.renderTileTextContent(incident)}
887
- </div>`;
888
- }
889
-
890
728
  private _generateHintText(hintIncident: Incident): string {
891
729
  let hint = "";
892
730
  const hintTemplates = this.i18n.HintTemplates[hintIncident.category];
893
731
  switch (hintIncident.category) {
894
- case "newsItem":
732
+ case Category.newsItem:
895
733
  hint = (
896
734
  hintTemplates[Math.round(Math.random() * hintTemplates.length)] || ""
897
735
  ).replace(/__TITLE__/, hintIncident.title);
898
736
  break;
899
- case "radioSong":
737
+ case Category.radioSong:
900
738
  // The title property of radioSongs always follow this pattern: track - artist
901
739
  const track = hintIncident.title.replace(/(.*?)\s+\-.*/, "$1");
902
740
  const artist = hintIncident.title.replace(/.*\-(.*)/, "$1");
@@ -907,77 +745,40 @@ export class GuessTheYear extends LitElement {
907
745
  .replace(/__ARTIST__/, artist)
908
746
  .replace(/__TRACK__/, track);
909
747
  break;
910
- case "cinemaMovie":
748
+ case Category.cinemaMovie:
911
749
  hint = (
912
750
  hintTemplates[Math.round(Math.random() * hintTemplates.length)] ||
913
751
  hintTemplates[0]
914
752
  ).replace(/__TITLE__/, hintIncident.title);
915
753
  break;
916
- case "tech":
754
+ case Category.tech:
917
755
  hint = (
918
756
  hintTemplates[Math.round(Math.random() * hintTemplates.length)] ||
919
757
  hintTemplates[0]
920
758
  ).replace(/__TITLE__/, hintIncident.title);
921
759
  break;
922
- case "newsPresenter":
760
+ case Category.newsPresenter:
923
761
  hint = (
924
762
  hintTemplates[Math.round(Math.random() * hintTemplates.length)] ||
925
763
  hintTemplates[0]
926
- ).replace(/__TITLE__/, hintIncident.title);
764
+ ).replace(/__TITLE__/, hintIncident.title || hintIncident.text);
927
765
  break;
928
- case "sports":
766
+ case Category.sports:
929
767
  hint = (
930
768
  hintTemplates[Math.round(Math.random() * hintTemplates.length)] ||
931
769
  hintTemplates[0]
932
- ).replace(/__TITLE__/, hintIncident.title);
770
+ ).replace(/__TITLE__/, hintIncident.title || hintIncident.text);
771
+ break;
772
+ case Category.showbizz:
773
+ hint = (
774
+ hintTemplates[Math.round(Math.random() * hintTemplates.length)] ||
775
+ hintTemplates[0]
776
+ ).replace(/__TITLE__/, hintIncident.title || hintIncident.text);
933
777
  break;
934
778
  }
935
779
  return hint;
936
780
  }
937
781
 
938
- renderHintTile(hint: Incident | undefined): TemplateResult {
939
- if (hint) {
940
- console.debug("renderHint");
941
- return html`<div class="guess-the-year-hint-tile">
942
- <h1 class="title">
943
- Hint ${this._intervalsPassed} <br />
944
- ${this._generateHintText(hint)}
945
- </h1>
946
- ${this.renderTileTextContent(hint)}
947
- </div>`;
948
- }
949
- return html``;
950
- }
951
-
952
- renderTileTitle(incident: Incident): TemplateResult {
953
- console.debug("renderTileTitle");
954
- if (incident.title) {
955
- return html`<h1 class="guess-the-year-tile-title">${incident.title}</h1>`;
956
- }
957
- return html``;
958
- }
959
-
960
- renderTileImage(incident: Incident): TemplateResult {
961
- console.debug("renderTileImage");
962
- if (this._tileShouldDisplayAnImage(incident)) {
963
- return html`<img
964
- @error=${(evt: Event) => {
965
- this._handleImageLoadError(evt, incident);
966
- }}
967
- src=${incident.image}
968
- />`;
969
- }
970
- return html``;
971
- }
972
-
973
- renderTileTextContent(incident: Incident): TemplateResult {
974
- console.debug("renderTileTextContent");
975
- if (incident.text) {
976
- return html`<p class="hint-text">${incident.text}</p>`;
977
- }
978
- return html``;
979
- }
980
-
981
782
  renderSources(): TemplateResult {
982
783
  console.debug("renderSources");
983
784
  if (!this.sources.length) {
@@ -991,30 +792,10 @@ export class GuessTheYear extends LitElement {
991
792
  `;
992
793
  }
993
794
 
994
- // private _incidentsTask: Task = new Task(this, {
995
- // task: async ([]) => {
996
- // console.debug('incidentsTask');
997
- // if (!this.loading) {
998
- // this.loading = true;
999
- // await this.setupNewGame();
1000
- // this.loading = false;
1001
- // }
1002
- // },
1003
- // args: () => [
1004
- // this.country,
1005
- // this.category,
1006
- // this.emotion,
1007
- // this.impact,
1008
- // this.date,
1009
- // this.from,
1010
- // this.to,
1011
- // ],
1012
- // });
1013
-
1014
795
  _handleImageLoadError = (evt: Event, incident: Incident) => {
1015
796
  // grab the image element that triggered the error
1016
797
  const targetImage = evt.target as HTMLImageElement;
1017
- console.info(`Error loading image: ${targetImage.src}`);
798
+ console.debug(`Error loading image: ${targetImage.src}`);
1018
799
 
1019
800
  // find out which no image source needs to be used
1020
801
  const noImageSrc = this.noImageSrc || NoImageImg;
package/src/index.html CHANGED
@@ -96,8 +96,7 @@
96
96
  <!-- 'Random from a date range' -->
97
97
  <section>
98
98
  <div class="big-container">
99
- <guess-the-year from="2010-01-01" to="2020-12-31" country="nl" category="newsItem" hint-interval-length="4"
100
- max-hints="3" auto-focus max-tries="2" show-duration show-feedback report-broken-images
99
+ <guess-the-year country="nl" category="newsItem" max-hints="3" report-broken-images
101
100
  no-image-src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAKCAYAAADGmhxQAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5wQMDCEDZE8l3wAAAAxpVFh0Q29tbWVudAAAAAAAvK6ymQAAABVJREFUOMtjYBgFo2AUjIJRMAooAQAGSgABkOHaHwAAAABJRU5ErkJggg==">
102
101
  </guess-the-year>
103
102
  </div>
@@ -92,7 +92,7 @@ export class ApiService {
92
92
  }
93
93
  });
94
94
 
95
- console.info([incidents, sourcesFoundInIncidents]);
95
+ console.debug([incidents, sourcesFoundInIncidents]);
96
96
 
97
97
  resolve({
98
98
  incident: firstIncidentInList,