Log events in visualization

This commit is contained in:
Dennis Schoepf 2021-08-03 14:17:38 +02:00
parent 0c542da265
commit 9c7161c8d9
11 changed files with 777 additions and 6 deletions

65
src/logger.ts Normal file
View file

@ -0,0 +1,65 @@
import firebase from 'firebase/app';
import 'firebase/database';
import store from './store';
const firebaseConfig = {
apiKey: 'AIzaSyCORIIdFkDBagiVf0IeK0UxZL1qv0m90_E',
authDomain: 'codewanderer-d9212.firebaseapp.com',
databaseURL: 'https://codewanderer-d9212-default-rtdb.europe-west1.firebasedatabase.app',
projectId: 'codewanderer-d9212',
storageBucket: 'codewanderer-d9212.appspot.com',
messagingSenderId: '143940874668',
appId: '1:143940874668:web:d2f860b4fc5d4292cf8a09',
};
type LogEventType =
| 'CC'
| 'OC'
| 'RC'
| 'LI'
| 'LR'
| 'LS'
| 'LC'
| 'PI'
| 'PR'
| 'PS'
| 'PC'
| 'NI'
| 'NR'
| 'NS'
| 'NC'
| 'GF'
| 'SF'
| 'OTHER';
export interface LogEvent {
timestamp: number;
type: LogEventType;
message?: string;
additionalData?: any;
}
export class Logger {
database: firebase.database.Database;
constructor() {
firebase.initializeApp(firebaseConfig);
this.database = firebase.database();
}
public log(ev: LogEvent) {
console.log('Logging event');
const uid = store.getState().uid;
const logEvKey = this.database.ref(uid).child('logs').push().key;
this.database.ref(uid).update({ [`logs/${logEvKey}`]: ev });
}
public logPersonalData() {}
public logKnowledgeQuestions() {}
public logGeneralQuestions() {}
}
export const logger = new Logger();

View file

@ -2,8 +2,9 @@ import _ from 'lodash';
import { mp5 } from '../../main';
import { colors } from '../constants/colors';
import { generateRevealableCoords } from '../helpers';
import { logger } from '../logger';
import { Player } from '../sketchObjects/Player';
import { Revealable, RevealableInterface } from '../sketchObjects/Revealable';
import { Revealable, RevealableInterface, RevealableTypes } from '../sketchObjects/Revealable';
import store from '../store';
import { Coordinates } from '../types';
import { CompanionState } from '../ui/companion';
@ -92,9 +93,25 @@ export class DetailScene {
onSceneClick() {
this.revealableObjects.forEach((revObj) => {
if (revObj.isHovered) {
logger.log({
type:
revObj.type === RevealableTypes.CONTRIBUTOR
? 'NI'
: revObj.type === RevealableTypes.LEGACY
? 'LI'
: 'PI',
timestamp: Date.now(),
message: `Identified ${revObj.name}`,
});
this.wasHovered = true;
revObj.onClick();
} else {
logger.log({
type: 'RC',
timestamp: Date.now(),
});
this.player.reveal();
this.wasInteractedWith = true;
}

View file

@ -7,6 +7,7 @@ import { generateEdges } from '../helpers';
import { Scenes } from './scenes';
import projectMetadata from '../../metadata/project.json';
import { Area } from '../types';
import { logger } from '../logger';
export class OverviewScene {
player: Player;
@ -30,12 +31,24 @@ export class OverviewScene {
this.edges.forEach((edge, i) => {
const dist = mp5.dist(mp5.mouseX, mp5.mouseY, edge.x, edge.y);
if (dist < edge.r) {
logger.log({
type: 'OC',
timestamp: Date.now(),
message: 'Click outside edge',
});
store.getState().setProjectMetadata(edge.name);
store.setState({
showScore: true,
currentSubproject: edge.name,
currentScene: Scenes.DETAIL,
});
} else {
logger.log({
type: 'OC',
timestamp: Date.now(),
message: 'Click on edge',
});
}
});
}
@ -52,6 +65,11 @@ export class OverviewScene {
store.setState({ finishedGame: true });
setTimeout(() => {
logger.log({
timestamp: Date.now(),
type: 'GF',
});
store.getState().addUserMessage({
text: "Nice! 😎 You made it all the way through. Now I would be very thankful if you could take some time to answer the following questions. Don't overthink the answers and write down everything that comes to your mind. The more input you give, the better no matter how well it is formulated!",
inputWanted: false,
@ -62,6 +80,12 @@ export class OverviewScene {
this.edges.forEach((edgeShape) => {
if (store.getState().finishedSubProjects.some((fsp) => fsp === edgeShape.name)) {
logger.log({
type: 'SF',
timestamp: Date.now(),
message: `Finished subproject: ${edgeShape.name}`,
});
edgeShape.finished = true;
}

View file

@ -2,6 +2,7 @@ import { combineLatest } from 'rxjs';
import { mp5 } from '../../main';
import { areasColliding, playerHead$, revealedArea$ } from '../area';
import { colors } from '../constants/colors';
import { logger } from '../logger';
import store from '../store';
import { Area } from '../types';
@ -85,6 +86,17 @@ export class Revealable {
this.state = RevealableStates.FOUND;
} else if (isRevealed && !isHovered) {
this.state = RevealableStates.REVEALED;
logger.log({
type:
this.type === RevealableTypes.CONTRIBUTOR
? 'NR'
: this.type === RevealableTypes.LEGACY
? 'LR'
: 'PR',
timestamp: Date.now(),
message: `Revealed ${this.name}`,
});
} else {
this.state = RevealableStates.HIDDEN;
}
@ -120,6 +132,7 @@ export class Revealable {
this.wasInteractedWith = true;
store.getState().addInfoMessage({
type: this.type,
headline: this.name,
innerHTML: this.contents,
imgUrl: this.imageUrl,

View file

@ -24,12 +24,14 @@ export interface State {
finishedGame: boolean;
revealablesFinished: number;
showScore: boolean;
uid: string;
}
const store = create<State>(
devtools((set) => ({
uid: null,
showScore: false,
currentIntroStep: 0,
currentIntroStep: 1,
revealablesFinished: 0,
currentScene: Scenes.OVERVIEW,
currentSubproject: null,

View file

@ -1,4 +1,5 @@
import anime from 'animejs/lib/anime.es';
import { logger } from '../logger';
import store from '../store';
export enum CompanionState {
@ -93,6 +94,11 @@ export class Companion {
// Hide Message
this.messageRef.style.display = 'none';
store.setState({ companionState: CompanionState.IDLE });
logger.log({
type: 'CC',
timestamp: Date.now(),
message: 'Close message',
});
if (this.message.onNext) {
this.message.onNext();
@ -195,6 +201,10 @@ export class Companion {
}
store.setState({ companionState: newCompanionState });*/
logger.log({
type: 'CC',
timestamp: Date.now(),
});
}
handleMouseEnter() {

View file

@ -1,6 +1,9 @@
import { logger } from '../logger';
import { RevealableTypes } from '../sketchObjects/Revealable';
import store from '../store';
export interface InfoMessageType {
type: RevealableTypes;
headline: string;
innerHTML: string;
imgUrl?: string;
@ -8,6 +11,8 @@ export interface InfoMessageType {
}
export class InfoMessage {
type: RevealableTypes;
name: string;
infoMessage: HTMLElement;
infoMessageHeadline: HTMLElement;
infoMessageContents: HTMLElement;
@ -39,6 +44,9 @@ export class InfoMessage {
const newMessage = state.infoMessages[state.infoMessages.length - 1];
this.setContents(newMessage.headline, newMessage.innerHTML);
this.type = newMessage.type;
this.name = newMessage.headline;
if (newMessage.imgUrl) {
this.setImg(newMessage.imgUrl);
} else {
@ -72,11 +80,33 @@ export class InfoMessage {
}
private show() {
logger.log({
type:
this.type === RevealableTypes.CONTRIBUTOR
? 'NS'
: this.type === RevealableTypes.LEGACY
? 'LS'
: 'PS',
timestamp: Date.now(),
message: `Showing info message for ${this.name}`,
});
this.infoMessage.style.display = 'block';
this.backdrop.style.display = 'block';
}
private hide() {
logger.log({
type:
this.type === RevealableTypes.CONTRIBUTOR
? 'NC'
: this.type === RevealableTypes.LEGACY
? 'LC'
: 'PC',
timestamp: Date.now(),
message: `Closing info message for ${this.name}`,
});
this.infoMessage.style.display = 'none';
this.backdrop.style.display = 'none';
}

View file

@ -1,3 +1,4 @@
import { logger } from '../logger';
import { Scenes } from '../scenes/scenes';
import store from '../store';
@ -107,6 +108,11 @@ export class Intro {
return;
} else {
this.errorRef.style.display = 'none';
store.setState({
uid: `${Date.now()}_${name.replace(/[^a-zA-Z ]/g, '').toLowerCase()}`,
});
this.sendDemographicData(name, age, background, experience);
}
}