@@ -187,6 +206,7 @@ import ErrorNotification from '@/components/common/ErrorNotification';
import Modal from '@/components/common/Modal';
import SubmitModal from '@/components/problem/SubmitModal';
import ResultModal from './result_modal/ResultModal';
+import EnterConfirmationModal from './EnterConfirmationModal';
import Tag from './Tag';
@@ -198,6 +218,7 @@ export default {
showStandingsModal: false,
showResultListModal: false,
showSubmitModal: false,
+ showConfirmationModal: false,
activeTab: 0,
diff: 300000,
};
@@ -216,6 +237,8 @@ export default {
'participants',
'id',
'error',
+ 'duration',
+ 'flexibleCreatedAt',
]),
...mapState('koneko/timeDiff', [
'timeDiff',
@@ -224,7 +247,15 @@ export default {
'canEnter',
'isEntered',
'isWriter',
+ 'isFlexibleContest',
+ 'flexibleEndAt',
]),
+ enterable() {
+ return this.canEnter &&
+ !this.isEntered &&
+ this.problems === null
+ ;
+ },
countDownTimer() {
if (this.diff < 0) return 'Already started';
const DD = `00${Math.floor(this.diff / 1000 / 60 / 60 / 24)}`.slice(-2);
@@ -284,6 +315,13 @@ export default {
await this.getResults();
this.showResultListModal = true;
},
+ myEnter() {
+ if (this.isFlexibleContest) {
+ this.showConfirmationModal = true;
+ } else {
+ this.enter();
+ }
+ },
num2alpha(num) {
return String.fromCharCode(97 + num);
},
@@ -308,6 +346,7 @@ export default {
Tag,
Modal,
Problem,
+ EnterConfirmationModal,
ErrorNotification,
SubmitModal,
ResultModal,
diff --git a/src/components/contest/EnterConfirmationModal.vue b/src/components/contest/EnterConfirmationModal.vue
new file mode 100644
index 0000000..35057eb
--- /dev/null
+++ b/src/components/contest/EnterConfirmationModal.vue
@@ -0,0 +1,49 @@
+
+
+
+ 参加するとすぐにコンテストが始まります。
+ コンテスト時間は、参加から{{Math.floor(duration / 60)}}分です
+
+
+
+
+
+
+
+
+
diff --git a/src/store/modules/contests/index.js b/src/store/modules/contests/index.js
index 3745799..e195951 100644
--- a/src/store/modules/contests/index.js
+++ b/src/store/modules/contests/index.js
@@ -19,6 +19,8 @@ export default {
requiredWatching: false,
isWaitingJudge: true,
error: null,
+ duration: null,
+ flexibleCreatedAt: null,
},
getters: {
isWriter({ writers }, _, rootState) {
@@ -30,6 +32,15 @@ export default {
canEnter(_, { isWriter, isEntered }) {
return !isEntered && !isWriter;
},
+ isFlexibleContest({ duration }) {
+ return !!duration;
+ },
+ flexibleEndAt({ flexibleCreatedAt, duration }) {
+ if (flexibleCreatedAt === null) return null;
+ const tmp = new Date(flexibleCreatedAt);
+ tmp.setSeconds(tmp.getSeconds() + duration);
+ return tmp;
+ },
},
mutations: {
setContestData(state, contestData) {
@@ -48,8 +59,9 @@ export default {
name: v.name, displayName: v.displayName, id: v.id,
}));
state.participants = contestData.participants.map(v => ({
- name: v.name, displayName: v.displayName, id: v.id,
+ name: v.user.name, displayName: v.user.displayName, id: v.user.id,
}));
+ state.duration = contestData.duration ? contestData.duration / 1000000000 : null;
},
setStatusesWatcherFlag(state) {
state.statusesWatcherFlag = true;
@@ -73,12 +85,15 @@ export default {
});
state.isWaitingJudge = state.problems.some(({ status }) => status < 2 && status > -1);
},
+ setFlexibleCreatedAt(state, createdAt) {
+ state.flexibleCreatedAt = createdAt;
+ },
waitJudge(state) {
state.isWaitingJudge = true;
},
setParticipants(state, participants) {
state.participants = participants.map(v => ({
- name: v.name, displayName: v.displayName, id: v.id,
+ name: v.user.name, displayName: v.user.displayName, id: v.user.id,
}));
},
setError(state, error) {
@@ -86,10 +101,18 @@ export default {
},
},
actions: {
- async getContest({ commit, rootState }, contestID) {
+ async getContest({ state, commit, rootState }, contestID) {
try {
const res = await api.getContest(rootState.koneko.sessionID, contestID);
commit('setContestData', res.data);
+ if (state.duration) {
+ for (let i = 0; i < res.data.participants.length; i += 1) {
+ if (rootState.koneko.user.id === res.data.participants[i].user.id) {
+ commit('setFlexibleCreatedAt', new Date(res.data.participants[i].createdAt));
+ break;
+ }
+ }
+ }
commit('setRequiredWatching', true);
} catch (e) {
commit('setError', e);
@@ -128,6 +151,14 @@ export default {
try {
const res = await api.enterContest(rootState.koneko.sessionID, state.id);
commit('setParticipants', res.data.participants);
+ if (state.duration) {
+ for (let i = 0; i < res.data.participants.length; i += 1) {
+ if (rootState.koneko.user.id === res.data.participants[i].user.id) {
+ commit('setFlexibleCreatedAt', new Date(res.data.participants[i].createdAt));
+ break;
+ }
+ }
+ }
} catch (e) {
commit('setError', e);
}