You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

317 lines
10 KiB

<template>
<div class="panel panel-default scorecard" v-if="show">
<div class="panel-heading">
<div class="team">
<span class="team-icon" :style="'background-color: #'+tweet.team_color"></span>
<span class="team-name">{{ tweet.team_name }}</span>
</div>
<h2>{{ tweet.mission }}</h2>
<button type="button" class="close" v-on:click="dismiss"><span>&times;</span></button>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-8">
<div class="profile">
<img :src="tweet.player_photo" :style="'border-color: #'+tweet.team_color">
<span><a :href="'https://twitter.com/'+tweet.player_username">@{{ tweet.player_username }}</a></span>
</div>
<div class="tweet">
<div class="text">{{ tweet.text }}</div>
<div v-if="tweet.photos">
<div :class="'multi-photo photos-'+tweet.photos.length" v-if="tweet.photos">
<div v-for="img in tweet.photos" class="photo" :style="'background-image:url('+img+')'" :data-featherlight="img">
<img :src="img">
</div>
</div>
<div class="multi-photo-clear"></div>
</div>
</div>
<div class="tweet-reply" v-if="showReplyBox">
<div class="top">
<textarea class="form-control" rows="2" v-model="replyText" style="margin-bottom: 4px;" :disabled="replyInProgress"></textarea>
</div>
<div class="bottom">
<div class="fill"></div>
<img src="/twitter.ico" width="16">
<div class="remaining-chars">{{ replyTextCharsRemaining }}</div>
<button class="btn btn-primary" :disabled="isTweetReplyDisabled" v-on:click="sendReply">Reply</button>
</div>
</div>
<div class="tweet-actions">
<button type="button" class="btn btn-success" v-on:click="scoreTweet" :disabled="isAcceptDisabled">Accept</button>
<button type="button" class="btn btn-danger" v-on:click="rejectTweet">Reject</button>
</div>
</div>
<div class="col-md-4">
<!-- MISSION 1 #transitspy -->
<template v-if="tweet.mission_id == 1">
<p class="instructions">
The photo must show the sign with the transit line
</p>
<div class="form-group">
<select class="form-control" v-model="selectedTransitLine">
<option value=""></option>
<option v-for="line in lines" :value="line.id">{{ line.name }}</option>
</select>
</div>
<div class="form-group">
<input type="text" v-model="selectedNonTrimetLine" placeholder="Non-Trimet Line" class="form-control">
</div>
</template>
<!-- MISSION 2 #intercept -->
<template v-if="tweet.mission_id == 2">
<p class="instructions">
<ul>
<li>Photo must show the sign with the transit center</li>
<li>Bonus points if another team and their pennant are visible!</li>
</ul>
</p>
<div class="form-group">
<select class="form-control" v-model="selectedTransitCenter">
<option value=""></option>
<option v-for="stop in centers" :value="stop.id">{{ stop.name }}</option>
</select>
</div>
<div class="form-group">
<div class="checkbox">
<label>
<input type="checkbox" v-model="selectedPhotoHasAnotherTeam">
Another team is in the photo
</label>
</div>
</div>
</template>
<!-- MISSION 3 #airlair -->
<template v-if="tweet.mission_id == 3">
<p class="instructions">
<ul>
<li>Make sure this photo is on the tram or at the top tram station</li>
<li>Reject if it shows the rooftop with the code!</li>
</ul>
</p>
</template>
<!-- MISSION 4 #transittea -->
<template v-if="tweet.mission_id == 4">
<p class="instructions">
<ul>
<li>The photo must include the radio</li>
<li>Reject if it shows the decoded message</li>
</ul>
</p>
</template>
<!-- MISSION 5 #sing -->
<template v-if="tweet.mission_id == 5">
<p class="instructions">
Accept a photo of either a team member singing, or a photo of tipping the bus driver
</p>
<div class="form-group">
<label>
<input type="checkbox" v-model="selectedM5Singing">
Singing
</label>
<br>
<label>
<input type="checkbox" v-model="selectedM5Tipping">
Tipping the driver
</label>
</div>
</template>
<!-- MISSION 6 #passport -->
<template v-if="tweet.mission_id == 6">
<p class="instructions">
The photo must show all team members with their completed visas
</p>
</template>
<!-- MISSION 7 #document -->
<template v-if="tweet.mission_id == 7">
<p class="instructions">
Accept a photo that completes one of the below documents:
</p>
<div class="form-group">
<div v-for="doc in documents" class="radio">
<label>
<input type="radio" name="selectedDocument" v-model="selectedDocument" :value="doc.id">
{{ doc.description }}
</label>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</template>
<script>
module.exports = {
props: ['show', 'tweet'],
data () {
return {
documents: [],
centers: [],
lines: [],
replyText: '',
replyTextCharsRemaining: 140,
replyInProgress: false,
showReplyBox: true,
selectedDocument: null,
selectedTransitCenter: null,
selectedTransitLine: null,
selectedNonTrimetLine: '',
selectedPhotoHasAnotherTeam: false,
selectedM5Singing: false,
selectedM5Tipping: false
}
},
computed: {
isAcceptDisabled() {
if(this.show) {
switch(this.tweet.mission_id) {
case 1:
return this.selectedTransitLine == null && this.selectedNonTrimetLine == '';
case 2:
return this.selectedTransitCenter == null;
case 3:
case 4:
case 6:
// Nothing to check
return false;
case 5:
return this.selectedM5Singing == false && this.selectedM5Tipping == false;
case 7:
return this.selectedDocument == null;
default:
return true;
}
} else {
return true;
}
},
isTweetReplyDisabled() {
return this.replyText == '' || this.replyInProgress || this.replyTextCharsRemaining < 0;
}
},
methods: {
clearState() {
this.selectedDocument = null;
this.selectedTransitCenter = null;
this.selectedTransitLine = null;
this.selectedNonTrimetLine = '';
this.selectedPhotoHasAnotherTeam = false;
this.selectedM5Singing = false;
this.selectedM5Tipping = false;
this.replyText = '';
this.showReplyBox = true;
},
dismiss() {
this.clearState();
this.$emit('dismiss');
},
rejectTweet() {
$.post("/dashboard/reject-tweet", {
tweet_id: this.tweet.tweet_id
}, function() {
this.clearState();
this.$emit('complete');
}.bind(this));
},
scoreTweet() {
var score_data = {};
switch(this.tweet.mission_id) {
case 1:
score_data['m1_complete'] = 1;
score_data['m1_transit_line_id'] = this.selectedTransitLine;
score_data['m1_non_trimet'] = this.selectedNonTrimetLine;
break;
case 2:
score_data['m2_complete'] = this.selectedTransitCenter ? 1 : 0;
score_data['m2_transit_center_id'] = this.selectedTransitCenter;
score_data['m2_with_other_team'] = this.selectedPhotoHasAnotherTeam ? 1 : 0;
break;
case 3:
score_data['m3_complete'] = 1;
break;
case 4:
score_data['m4_complete'] = 1;
break;
case 5:
score_data['m5_complete'] = this.selectedM5Singing ? 1 : 0;
score_data['m5_tip'] = this.selectedM5Tipping ? 1 : 0;
break;
case 6:
score_data['m6_complete'] = 1;
break;
case 7:
score_data['m7_document_id'] = this.selectedDocument;
break;
}
$.post("/dashboard/score-tweet", {
tweet_id: this.tweet.tweet_id,
score_data: score_data
}, function(){
this.clearState();
this.$emit('complete');
}.bind(this));
},
sendReply() {
this.replyInProgress = true;
$.post("/dashboard/reply", {
tweet_id: this.tweet.tweet_id,
text: this.replyText
}, function(response){
if(response.result == "ok") {
this.replyText = '';
}
this.replyInProgress = false;
}.bind(this));
// setTimeout(function(){ this.replyInProgress = false; this.showReplyBox = false; }.bind(this), 1000);
}
},
watch: {
// https://vuejs.org/v2/guide/computed.html#Watchers
show: function(val) {
if(val) {
// https://vuejs.org/v2/guide/reactivity.html#Async-Update-Queue
Vue.nextTick(function() {
$(".multi-photo .photo").featherlight();
}.bind(this));
}
},
replyText: function(val) {
this.replyTextCharsRemaining = 140 - twitter.getTweetLength(val);
}
},
created() {
$.get("/dashboard/dropdowns", function(response){
this.centers = response.transit_centers;
this.lines = response.transit_lines;
this.documents = response.documents;
}.bind(this));
}
}
</script>