93b3353a8ba12ae769b21b9c273b0a362ca0b2e9
1 Vue
.component('my-problems', {
5 problems: [], //oldest first
6 myProblems: [], //same, but only mine
7 display: "list", //or "myList"
8 curIdx: -1, //index in (current) problems array
10 // New problem (to upload), or existing problem to edit:
12 id: 0, //defined if it's an edit
20 // TODO: problem edit, just fill modalProb + adjust AJAX call
21 // problem delete: just AJAX call + confirm
23 <div class="col-sm-12 col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
24 <div id="problemControls" class="button-group">
25 <button :aria-label='translate("Previous problem(s)")' class="tooltip" @click="showNext('backward')">
26 <i class="material-icons">skip_previous</i>
28 <button :aria-label='translate("Add a problem")' class="tooltip" onClick="doClick('modal-newproblem')">
29 {{ translate("New") }}
31 <button :aria-label='translate("Next problem(s)")' class="tooltip" @click="showNext('forward')">
32 <i class="material-icons">skip_next</i>
35 <div id="mainBoard" v-show="curIdx>=0">
36 <div id="instructions-div" class="section-content">
37 <p id="problem-instructions">{{ curProb.instructions }}</p>
39 <my-board :fen="curProb.fen"></my-board>
40 <div id="solution-div" class="section-content">
41 <h3 class="clickable" @click="showSolution = !showSolution">
42 {{ translations["Show solution"] }}
44 <p id="problem-solution" v-show="showSolution">{{ curProb.solution }}</p>
45 <div class="button-group" v-show="curProb.uid==userId">
47 <button>Delete</button>
51 <button v-if="!!userId" @click="toggleListDisplay()">My problems (only)</button>
52 <my-problem-summary v-show="curIdx<0"
53 v-for="(p,idx) in sortedProblems" @click="setCurIdx(idx)"
54 v-bind:prob="p" v-bind:preview="false" v-bind:key="p.id">
56 <input type="checkbox" id="modal-newproblem" class="modal">
57 <div role="dialog" aria-labelledby="modalProblemTxt">
58 <div v-show="!modalProb.preview" class="card newproblem-form">
59 <label for="modal-newproblem" class="modal-close"></label>
60 <h3 id="modalProblemTxt">{{ translate("Add a problem") }}</h3>
61 <form @submit.prevent="previewNewProblem()">
63 <label for="newpbFen">FEN</label>
64 <input id="newpbFen" type="text" v-model="modalProb.fen"
65 :placeholder='translate("Full FEN description")'/>
68 <p class="emphasis">{{ translate("Safe HTML tags allowed") }}</p>
69 <label for="newpbInstructions">{{ translate("Instructions") }}</label>
70 <textarea id="newpbInstructions" v-model="modalProb.instructions"
71 :placeholder='translate("Describe the problem goal")'></textarea>
72 <label for="newpbSolution">{{ translate("Solution") }}</label>
73 <textarea id="newpbSolution" v-model="modalProb.solution"
74 :placeholder='translate("How to solve the problem?")'></textarea>
75 <button class="center-btn">{{ translate("Preview") }}</button>
79 <div v-show="modalProb.preview" class="card newproblem-preview">
80 <label for="modal-newproblem" class="modal-close"></label>
81 <my-problem-summary v-bind:prob="modalProb" v-bind:preview="true"></my-problem-summary>
82 <div class="button-group">
83 <button @click="modalProb.preview=false">{{ translate("Cancel") }}</button>
84 <button @click="sendNewProblem()">{{ translate("Send") }}</button>
91 sortedProblems: function() {
92 // Newest problem first
93 return this.curProblems
.sort((a
,b
) => a
.added
- b
.added
);
99 return this.problems
[this.curIdx
];
101 return this.myProblems
[this.curIdx
];
105 created: function() {
106 if (location
.hash
.length
> 0)
108 this.getOneProblem(location
.hash
.slice(1));
109 this.curIdx
= 0; //TODO: a bit more subtle, depending if it's my problem or not (set display)
113 // Fetch most recent problems from server
114 this.fetchProblems("backward"); //TODO: backward in time from the future. Second argument?
118 setCurIndex: function(idx
) {
120 location
.hash
= "#" + idx
;
122 translate: function(text
) {
123 return translations
[text
];
125 curProblems: function() {
126 switch (this.display
)
129 return this.problems
;
131 return this.myProblems
;
134 // TODO: dans tous les cas si on n'affiche qu'un seul problème,
135 // le curseur ne doit se déplacer que d'une unité.
136 showNext: function(direction
) {
138 this.fetchProblems(direction
);
139 let curProbs
= this.curProblems();
140 if ((this.curIdx
> 0 && direction
=="backward")
141 || (this.curIdx
< curProbs
.length
-1 && direction
=="forward"))
143 this.setCurIdx(this.curIdx
+ (direction
=="forward" ? 1 : -1));
147 const curSize
= curProbs
.length
;
148 this.fetchProblems(direction
);
152 this.setCurIndex(--this.curIdx
);
155 if (this.curIdx
== this.problems
.length
- 1)
156 this.fetchProblems("forward");
159 location
.hash
= this.curIdx
;
161 toggleListDisplay: function() {
162 this.display
= (this.display
== "list" ? "myList" : "list");
164 // TODO: modal "there are no more problems"
165 fetchProblems: function(direction
) {
166 const problems
= if ... this.problems
... ou
this.myProblems
;
167 if (this.problems
.length
== 0)
168 return; //what could we do?! -------> ask problems older than MAX_NUMBER + backward
169 // Search for newest date (or oldest)
170 let last_dt
= this.problems
[0].added
;
171 for (let i
=0; i
<this.problems
.length
; i
++)
173 if ((direction
== "forward" && this.problems
[i
].added
> last_dt
) ||
174 (direction
== "backward" && this.problems
[i
].added
< last_dt
))
176 last_dt
= this.problems
[i
].added
;
179 ajax("/problems/" + variant
.name
, "GET", { //TODO: use variant._id ?
180 direction: direction
,
183 if (response
.problems
.length
> 0)
185 this.problems
= response
.problems
186 .sort((p1
,p2
) => { return p1
.added
- p2
.added
; });
187 this.setCurIndex(response
.problems
.length
- 1);
191 previewNewProblem: function() {
192 if (!V
.IsGoodFen(this.newProblem
.fen
))
193 return alert(translations
["Bad FEN description"]);
194 if (this.newProblem
.instructions
.trim().length
== 0)
195 return alert(translations
["Empty instructions"]);
196 if (this.newProblem
.solution
.trim().length
== 0)
197 return alert(translations
["Empty solution"]);
198 this.modalProb
.preview
= true;
200 // TODO: adjust for update too
201 sendNewProblem: function() {
202 // Send it to the server and close modal
203 ajax("/problems/" + variant
.name
, "POST", { //TODO: with variant._id ?
204 fen: this.newProblem
.fen
,
205 instructions: this.newProblem
.instructions
,
206 solution: this.newProblem
.solution
,
208 this.modalProb
.added
= Date
.now();
209 this.curProblems().push(JSON
.parse(JSON
.stringify(this.modalProb
)));
210 document
.getElementById("modal-newproblem").checked
= false;
211 this.modalProb
.preview
= false;
214 // TODO: AJAX for problem deletion