115 lines
4.4 KiB
JavaScript
115 lines
4.4 KiB
JavaScript
var api = require('../../utils/api');
|
|
var bracket = require('../../utils/bracket');
|
|
|
|
Page({
|
|
data: { loading: true, error: '', test: null, left: null, right: null, matches: [], mode: 'single', round: 1, progress: 0, completed: 0, totalDecisions: 0 },
|
|
onLoad: function (options) {
|
|
this.slug = options.slug;
|
|
this.load();
|
|
},
|
|
load: function () {
|
|
var self = this;
|
|
api.request('/api/v1/tests/' + this.slug).then(function (test) {
|
|
self.test = test;
|
|
self.state = bracket.create(test.candidates);
|
|
self.totalDecisions = test.candidates.length - 1;
|
|
self.refreshPair();
|
|
self.setData({ loading: false, test: test, totalDecisions: self.totalDecisions });
|
|
}).catch(function (error) { self.setData({ loading: false, error: error.message || '加载失败' }); });
|
|
},
|
|
refreshPair: function () {
|
|
var pair = bracket.current(this.state);
|
|
if (this.visibleRound !== this.state.round) {
|
|
this.visibleRound = this.state.round;
|
|
this.multiOffset = 0;
|
|
}
|
|
var offset = this.multiOffset || 0;
|
|
var matches = this.state.matches.slice(offset, offset + 4).map(function (match, index) {
|
|
return { index: offset + index, left: match.left, right: match.right, winner: match.winner };
|
|
});
|
|
this.setData({
|
|
left: pair && pair[0],
|
|
right: pair && pair[1],
|
|
matches: matches,
|
|
round: this.state.round,
|
|
completed: this.state.decisions.length,
|
|
progress: Math.round(this.state.decisions.length / this.totalDecisions * 100)
|
|
});
|
|
},
|
|
setMode: function (event) {
|
|
this.setData({ mode: event.currentTarget.dataset.mode });
|
|
},
|
|
choose: function (event) {
|
|
if (this.choosing) return;
|
|
this.choosing = true;
|
|
var side = event.currentTarget.dataset.side;
|
|
var winner = side === 'left' ? this.data.left : this.data.right;
|
|
var finished = bracket.choose(this.state, winner);
|
|
if (finished) this.complete();
|
|
else {
|
|
this.refreshPair();
|
|
var self = this;
|
|
setTimeout(function () { self.choosing = false; }, 220);
|
|
}
|
|
},
|
|
chooseMatch: function (event) {
|
|
if (this.choosing) return;
|
|
var matchIndex = Number(event.currentTarget.dataset.match);
|
|
var side = event.currentTarget.dataset.side;
|
|
var match = this.state.matches[matchIndex];
|
|
if (!match || match.winner || !match.right) return;
|
|
this.choosing = true;
|
|
var winner = side === 'left' ? match.left : match.right;
|
|
var beforeRound = this.state.round;
|
|
var finished = bracket.chooseAt(this.state, matchIndex, winner);
|
|
if (finished) this.complete();
|
|
else {
|
|
this.refreshPair();
|
|
var self = this;
|
|
setTimeout(function () {
|
|
if (beforeRound === self.state.round) {
|
|
var offset = self.multiOffset || 0;
|
|
var block = self.state.matches.slice(offset, offset + 4);
|
|
if (block.length && block.every(function (item) { return item.winner; })) self.multiOffset = offset + 4;
|
|
}
|
|
self.refreshPair();
|
|
self.choosing = false;
|
|
}, 360);
|
|
}
|
|
},
|
|
touchStart: function (event) { this.touchX = event.touches[0].clientX; },
|
|
touchEnd: function (event) {
|
|
if (this.data.mode !== 'swipe' || this.touchX == null) return;
|
|
var delta = event.changedTouches[0].clientX - this.touchX;
|
|
this.touchX = null;
|
|
if (Math.abs(delta) < 55) return;
|
|
this.choose({ currentTarget: { dataset: { side: delta < 0 ? 'left' : 'right' } } });
|
|
},
|
|
complete: function () {
|
|
var self = this;
|
|
var champion = this.state.pool[0];
|
|
var finalDecision = this.state.decisions[this.state.decisions.length - 1];
|
|
var runnerUpId = finalDecision.left_id === champion.id ? finalDecision.right_id : finalDecision.left_id;
|
|
this.setData({ progress: 100, submitting: true });
|
|
api.ensureLogin().then(function () {
|
|
return api.request('/api/v1/tests/' + self.slug + '/runs', {
|
|
method: 'POST',
|
|
data: {
|
|
app_key: 'hub',
|
|
champion_id: champion.id,
|
|
runner_up_id: runnerUpId,
|
|
ranking_ids: bracket.ranking(self.state),
|
|
decisions: self.state.decisions
|
|
}
|
|
});
|
|
}).then(function (result) {
|
|
xhs.setStorageSync('pk_last_result', result);
|
|
xhs.redirectTo({ url: '/pages/result/result?id=' + result.id });
|
|
}).catch(function (error) {
|
|
self.choosing = false;
|
|
self.setData({ submitting: false });
|
|
xhs.showModal({ title: '结果保存失败', content: error.message || '请检查网络后重试', showCancel: false });
|
|
});
|
|
}
|
|
});
|