Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor POIs so that Mobs can be displayed #131

Merged
merged 24 commits into from
Oct 19, 2016
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
055d9b2
Make mapPokePOI() a utility function instead of a static method
MajorBreakfast Oct 17, 2016
d8772f0
Call constructor, remove unusual Object.create() usage
MajorBreakfast Oct 17, 2016
fef4f67
Add button to manually show mob card
MajorBreakfast Oct 18, 2016
b9f78ac
Make poi-card compatible with sightings and mobs
MajorBreakfast Oct 18, 2016
798ae98
Merge branch 'develop' of https://github.com/PokemonGoers/Catch-em-al…
MajorBreakfast Oct 18, 2016
23b313f
Rename PokePOI to POI
MajorBreakfast Oct 18, 2016
0540a55
Rename PokeMob to Mob
MajorBreakfast Oct 18, 2016
4263399
Rename PokePrediction to Prediction
MajorBreakfast Oct 18, 2016
d112e48
Rename PokeSighting to Sighting
MajorBreakfast Oct 18, 2016
d86c856
Rename PokeGender to PokemonGender, PokeAttackCategory to PokemonAtta…
MajorBreakfast Oct 18, 2016
39c9960
Remove pokemon property from Sighting and Prediction
MajorBreakfast Oct 18, 2016
55ca79e
Refactor POI and its subclasses
MajorBreakfast Oct 18, 2016
1dd9ada
Replace Object.assign
MajorBreakfast Oct 18, 2016
101f2d0
PokeMob logo
MajorBreakfast Oct 18, 2016
0e503a9
Refactor poi-card layout and integrate mobs
MajorBreakfast Oct 18, 2016
6688ee6
Artificial tweets
MajorBreakfast Oct 18, 2016
84414db
Make POI#type a value property
MajorBreakfast Oct 18, 2016
451ffa6
Make tweet count text plural only
MajorBreakfast Oct 19, 2016
94e5d7a
Use elvis operator
MajorBreakfast Oct 19, 2016
569202d
Set Mob data from map data, refactor MobTweet type
MajorBreakfast Oct 19, 2016
73279c6
Extract poiFromMapEventData() into a module
MajorBreakfast Oct 19, 2016
ae01cc1
Show artifial mob button only in development mode
MajorBreakfast Oct 19, 2016
6599949
Use ngIf instead of hidden attribute
MajorBreakfast Oct 19, 2016
f8ace07
get isDevelopEnvironment()
MajorBreakfast Oct 19, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
646 changes: 646 additions & 0 deletions ionic2/app/assets/img/pokemon-mob.ai

Large diffs are not rendered by default.

368 changes: 368 additions & 0 deletions ionic2/app/assets/img/pokemon-mob.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 36 additions & 15 deletions ionic2/app/components/map/map.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { Component, ViewChild } from '@angular/core';
import { Events } from 'ionic-angular';
import { Geolocation } from 'ionic-native';

import { PokeSighting } from '../../models/poke-sighting';
import { PokePrediction } from '../../models/poke-prediction';
import { PokeMob } from '../../models/poke-mob';
import { Sighting } from '../../models/sighting';
import { Prediction } from '../../models/prediction';
import { Mob, MobTweet } from '../../models/mob';
import { POI } from '../../models/poi';
import { Filter } from '../../models/filter';

let PokeMap = require('pokemap-1');
Expand Down Expand Up @@ -46,9 +47,9 @@ export class MapComponent {
//this.map.filter(filter);
}

private onClick(pokePOI) {
console.debug('map:click', pokePOI);
this.events.publish('map:click', MapComponent.mapPokePOI(pokePOI));
private onClick(poi) {
console.debug('map:click', poi);
this.events.publish('map:click', poiFromMapEventData(poi));
}

private onMove(position) {
Expand All @@ -67,15 +68,35 @@ export class MapComponent {
this.map.navigate(start, destination);
})
}
}

private static mapPokePOI(pokePOI: Object): (PokeSighting | PokePrediction | PokeMob) {
if ('source' in pokePOI) {
return PokeSighting.fromObject(pokePOI);
} else if ('clusterId' in pokePOI) {
return PokeMob.fromObject(pokePOI);
} else {
throw new Error('PokePOI cannot be identified as PokeSighting or PokeMob:\n' + JSON.stringify(pokePOI));
}
function poiFromMapEventData(rawData: any) : POI {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no reason to use the function keyword

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that TypeScript feature?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and we are using it all over the place I think 😆 http://www.typescriptlang.org/docs/handbook/classes.html

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compile error. Am I doing something wrong?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you paste the error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TypeScript docu uses the keyword as well https://www.typescriptlang.org/docs/handbook/functions.html

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class ends before the function definition, I didn't realiize this on github.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, exactly.

Copy link
Contributor Author

@MajorBreakfast MajorBreakfast Oct 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@johartl Should I make this a static method or a utility function? What do you prefer? I and @WoH need another opinion

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer the static method

if ('source' in rawData) {
const sighting = new Sighting();
sighting.latitude = rawData.location.coordinates[1];
sighting.longitude = rawData.location.coordinates[0];
sighting.pokemonId = rawData.pokemonId;
sighting.source = rawData.source;
sighting.appearedOn = rawData.appearedOn;
return sighting;
} else if ('clusterId' in rawData) {
const mob = new Mob();
mob.clusterId = rawData.clusterId;
mob.timestamp = rawData.timestamp;
mob.latitude = rawData.coordinates[1];
mob.longitude = rawData.coordinates[0];
mob.tweets = rawData.tweets.map(t => {
return <MobTweet>{
id: t.id,
text: t.text,
latitude: t.coordinates[1],
longitude: t.coordinates[0],
timestamp: t.timestamp
}
})
return mob;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for returning an empty mob object here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the map already produce mobs? If so, what's the exact format of the event data?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if they already do. But the data should look like this PokemonGoers/PokeMap-2#32 (comment) which is exactly what our Mob class represents.
The best thing you can probably do is const mob = Mob.fromObject(rawData);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I just realized that you've removed the fromObject method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it from the model itself because it doesn't really belong in there.

} else {
throw new Error('POI cannot be identified as ' +
'Sighting or Mob:\n' + JSON.stringify(rawData));
}

}
2 changes: 1 addition & 1 deletion ionic2/app/components/poi-bubble/poi-bubble.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="circle" #circle>
<div class="circle-inner"></div>
<img [src]="pokePOI.pokemon.svgIcon">
<img [src]="pokemon.svgIcon">
</div>
1 change: 0 additions & 1 deletion ionic2/app/components/poi-bubble/poi-bubble.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
display: flex;
border-radius: 50%;
border: 1px solid #cacaca;
box-shadow: 0 0 4px 1px rgba(0,0,0,0.4);
padding: 10px;
}

Expand Down
7 changes: 4 additions & 3 deletions ionic2/app/components/poi-bubble/poi-bubble.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, Input, ViewChild, ElementRef, OnInit } from '@angular/core';

import { PokeSighting } from '../../models/poke-sighting';
import { Pokemon } from '../../models/pokemon';

@Component({
selector: 'poke-poi-bubble',
Expand All @@ -10,7 +10,8 @@ import { PokeSighting } from '../../models/poke-sighting';
})
export class POIBubbleComponent implements OnInit {

@Input() pokePOI: PokeSighting;
@Input() pokemon: Pokemon;
@Input() appearedOn: number;
@ViewChild('circle') circle: ElementRef;

arcHighlightColor = '#FFF75A';
Expand All @@ -19,7 +20,7 @@ export class POIBubbleComponent implements OnInit {
constructor() { }

ngOnInit() {
let appearedOn = (new Date(this.pokePOI.appearedOn)).getTime() / 1000;
let appearedOn = (new Date(this.appearedOn)).getTime() / 1000;
let now = Date.now() / 1000;
let diff = Math.max(Math.log((now -appearedOn) / 1000), 1);
let max = Math.log(30 * 86400 / 1000);
Expand Down
89 changes: 51 additions & 38 deletions ionic2/app/components/poi-card/poi-card.component.html
Original file line number Diff line number Diff line change
@@ -1,46 +1,59 @@
<div class="slide-card" #slideCard @slide="slideState">
<div class="poke-poi-card-content" *ngIf="pokePOI" [ngClass]="'poi-type-'+pokePOI.getType()">
<ion-row>
<div id="slide-card" #slideCard @slide="slideState">
<!-- Sightings -->
<div *ngIf="poi?.type == 'sighting' && pokemon">
<section class="side-section" id="sighting-side-section">
<poke-poi-bubble [pokemon]="pokemon"
[appearedOn]="poi.appearedOn"></poke-poi-bubble>
<div>
<poke-type [type]="type" *ngFor="let type of pokemon.types">
</poke-type>
</div>
</section>

<ion-col class="poke-column">
<ion-row>
<poke-poi-bubble [pokePOI]="pokePOI"></poke-poi-bubble>
</ion-row>
<ion-row>
<poke-type [type]="type" *ngFor="let type of pokePOI.pokemon.types">
</poke-type>
</ion-row>
</ion-col>

<ion-col style="flex-grow: 1;">
<ion-row>
<span class="poke-name">{{ pokePOI.pokemon.name }}</span>
<poke-rarity-badge [rarity]="pokePOI.pokemon.appearanceLikelihood">
</poke-rarity-badge>
</ion-row>
<ion-row class="poke-description">
{{ pokePOI.pokemon.description }}
</ion-row>
<section class="main-section" id="sighting-main-section">
<div class="name-and-rarity">
<span class="title">{{ pokemon.name }}</span>
<poke-rarity-badge [rarity]="pokemon.appearanceLikelihood">
</poke-rarity-badge>
</div>
<div class="description">{{ pokemon.description }}</div>
<div class="buttons">
<button clear (click)="showDirections()">
<ion-icon name="navigate"></ion-icon> Directions
</button>
<button clear (click)="launchPokeDex()">
<ion-icon name="book"></ion-icon> PokeDex
</button>
</div>
</section>

<div class="line" id="sighting-line"></div>
<div class="line-badge" id="sighting-line-badge">Pokemon Sighting</div>
</div>

<ion-row class="action-button-bar">
<button clear (click)="showDirections()">
<ion-icon name="navigate"></ion-icon>
Directions
</button>
<!-- Mobs -->
<div *ngIf="poi?.type == 'mob'">
<section class="side-section" id="mob-side-section">
<img src="img/pokemon-mob.svg" alt="Pokemon Logo">
</section>

<button clear (click)="launchPokeDex()">
<ion-icon name="book"></ion-icon>
PokeDex
</button>
</ion-row>
</ion-col>
</ion-row>
<section class="main-section" id="mob-main-section">
<div class="title">PokeMob</div>
<div class="description">
A lot of players seem to gather at this location!<br><br>
Based on {{ poi.tweets.length }} tweets.
</div>
<div class="buttons">
<button clear (click)="showDirections()">
<ion-icon name="navigate"></ion-icon> Directions
</button>
</div>
</section>

<div class="poke-poi-type-line"></div>
<div class="poke-poi-type-badge">
{{ getPOITypeBadgeLabel() }}
</div>
<section class="buttons-section" id="mob-buttons-section">
</section>

<div class="line" id="mob-line"></div>
<div class="line-badge" id="mob-line-badge">PokeMob</div>
</div>
</div>
140 changes: 58 additions & 82 deletions ionic2/app/components/poi-card/poi-card.component.scss
Original file line number Diff line number Diff line change
@@ -1,114 +1,90 @@
:host .slide-card {
min-height: 100px;
width: 100%;
#slide-card {
background: white;
position: absolute;
display: inline-block;
bottom: 0;
box-shadow: 0px -2px 3px 0 rgba(0,0,0,0.5);
position: absolute; right: 0; bottom: 0; left: 0;
box-shadow: 0 0 6px rgba(0, 0, 0, 0.8);
z-index: 99999;

.poke-poi-card-content {
padding-top: 12px;

.poke-picture {
flex-grow: 1;
}

.poke-name {
font-size: 28px;
> div {
margin: 0 auto;
max-width: 700px;
height: 170px;
padding: 10px;
display: flex;

/* General */
> .side-section {
width: 120px;
margin-right: 10px;
display: flex;
flex-direction: column;
align-items: center;
}

poke-rarity-badge {
margin-left: 10px;
align-self: center;
}
> .main-section {
flex: 1 0 0;
display: flex;
flex-direction: column;

.poke-description {
font-size: 12px;
color: #525252;
padding: 2px 0;
}
.title { font-size: 2em; font-weight: 300; }

.poke-column {
flex-grow: 0;
flex-basis: 120px;

ion-row {
justify-content: center;
> .description {
flex: 1 0 0;
color: #525252;
}

poke-poi-bubble {
width: 100px;
height: 100px;
}
> .buttons {
display: flex;
justify-content: flex-end;

poke-type {
margin: 16px 0 6px 0;
> button {
color: #123784;
padding: 4px 10px;
margin: 0px 2px;

ion-badge {
font-size: 10px;
padding: 2px 5px;
ion-icon { font-size: 26px; }
}
}
}

.action-button-bar {
justify-content: flex-end;
margin-top: 8px;

button {
color: #123784;
padding: 4px 10px;
margin: 0px 2px;

ion-icon {
font-size: 26px;
}
}
}

.poke-poi-type-line {
position: absolute;
top:0;
right: 0;
> .line {
position: absolute; right: 0; top: 0; left: 0;
height: 5px;
background: yellow;
display: inline-block;
width: 110%;
box-shadow: 4px 3px 4px -3px rgba(0, 0, 0, 0.75);
}

.poke-poi-type-badge {
position: absolute;
display: inline-block;
top: 0;
right: 0;
> .line-badge {
position: absolute; right: 0; top: 0;
padding: 3px 4px 2px 6px;
font-size: 12px;
font-weight: bold;
color: white;
}

&.poi-type-sighting {
.poke-poi-type-badge,
.poke-poi-type-line {
background: #123784;
}
/* Sightings only */
> #sighting-side-section {
> poke-poi-bubble { width: 100px; height: 100px; margin-bottom: 10px; }
> div { text-align: center; }
}

&.poi-type-prediction {
.poke-poi-type-badge,
.poke-poi-type-line {
background: #149062;
> #sighting-main-section {
poke-rarity-badge {
margin-left: 10px;
vertical-align: 35%;
}
}
> #sighting-line, > #sighting-line-badge { background: #149062; }


/* Predictions only */
> #prediction-line, > #prediction-line-badge { background: #123784; }

&.poi-type-mob {
.poke-poi-type-badge,
.poke-poi-type-line {
background: #ca1010;
/* Mobs only */
> #mob-side-section {
justify-content: center;

> img {
width: 100px;
display: block;
}
}
> #mob-line, > #mob-line-badge { background: #ca1010; }
}
}
Loading