nodeskini 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/README.md +31 -0
  2. package/client/archive/bundle.js +11528 -0
  3. package/client/archive/golem.html +60 -0
  4. package/client/archive/golemClient.js +595 -0
  5. package/client/archive/golembundle.js +11634 -0
  6. package/client/archive/sequencer.html +43 -0
  7. package/client/archive/sequenceurClient.js +815 -0
  8. package/client/archive/stylegolem.css +158 -0
  9. package/client/archive/stylesequenceur.css +204 -0
  10. package/client/clientListe/Sortable-master/.circleci/config.yml +33 -0
  11. package/client/clientListe/Sortable-master/.editorconfig +15 -0
  12. package/client/clientListe/Sortable-master/.github/ISSUE_TEMPLATE/bug-report.md +73 -0
  13. package/client/clientListe/Sortable-master/.github/ISSUE_TEMPLATE/custom-template.md +48 -0
  14. package/client/clientListe/Sortable-master/.github/ISSUE_TEMPLATE/feature-request.md +41 -0
  15. package/client/clientListe/Sortable-master/.jshintrc +25 -0
  16. package/client/clientListe/Sortable-master/.testcaferc.json +7 -0
  17. package/client/clientListe/Sortable-master/CONTRIBUTING.md +26 -0
  18. package/client/clientListe/Sortable-master/LICENSE +21 -0
  19. package/client/clientListe/Sortable-master/README.md +813 -0
  20. package/client/clientListe/Sortable-master/Sortable.js +3709 -0
  21. package/client/clientListe/Sortable-master/Sortable.min.js +2 -0
  22. package/client/clientListe/Sortable-master/Sortable.min.old.js +2 -0
  23. package/client/clientListe/Sortable-master/Sortable.min.old.old.js +2 -0
  24. package/client/clientListe/Sortable-master/babel.config.js +27 -0
  25. package/client/clientListe/Sortable-master/bower.json +30 -0
  26. package/client/clientListe/Sortable-master/entry/entry-complete.js +8 -0
  27. package/client/clientListe/Sortable-master/entry/entry-core.js +19 -0
  28. package/client/clientListe/Sortable-master/entry/entry-defaults.js +19 -0
  29. package/client/clientListe/Sortable-master/index.html +460 -0
  30. package/client/clientListe/Sortable-master/modular/sortable.complete.esm.js +3701 -0
  31. package/client/clientListe/Sortable-master/modular/sortable.core.esm.js +3698 -0
  32. package/client/clientListe/Sortable-master/modular/sortable.esm.js +3699 -0
  33. package/client/clientListe/Sortable-master/package-lock.json +5704 -0
  34. package/client/clientListe/Sortable-master/package.json +56 -0
  35. package/client/clientListe/Sortable-master/plugins/AutoScroll/AutoScroll.js +270 -0
  36. package/client/clientListe/Sortable-master/plugins/AutoScroll/README.md +80 -0
  37. package/client/clientListe/Sortable-master/plugins/AutoScroll/index.js +1 -0
  38. package/client/clientListe/Sortable-master/plugins/MultiDrag/MultiDrag.js +617 -0
  39. package/client/clientListe/Sortable-master/plugins/MultiDrag/README.md +96 -0
  40. package/client/clientListe/Sortable-master/plugins/MultiDrag/index.js +1 -0
  41. package/client/clientListe/Sortable-master/plugins/OnSpill/OnSpill.js +79 -0
  42. package/client/clientListe/Sortable-master/plugins/OnSpill/README.md +60 -0
  43. package/client/clientListe/Sortable-master/plugins/OnSpill/index.js +1 -0
  44. package/client/clientListe/Sortable-master/plugins/README.md +178 -0
  45. package/client/clientListe/Sortable-master/plugins/Swap/README.md +55 -0
  46. package/client/clientListe/Sortable-master/plugins/Swap/Swap.js +90 -0
  47. package/client/clientListe/Sortable-master/plugins/Swap/index.js +1 -0
  48. package/client/clientListe/Sortable-master/scripts/banner.js +8 -0
  49. package/client/clientListe/Sortable-master/scripts/build.js +17 -0
  50. package/client/clientListe/Sortable-master/scripts/esm-build.js +28 -0
  51. package/client/clientListe/Sortable-master/scripts/minify.js +11 -0
  52. package/client/clientListe/Sortable-master/scripts/test-compat.js +30 -0
  53. package/client/clientListe/Sortable-master/scripts/test.js +21 -0
  54. package/client/clientListe/Sortable-master/scripts/umd-build.js +15 -0
  55. package/client/clientListe/Sortable-master/src/Animation.js +175 -0
  56. package/client/clientListe/Sortable-master/src/BrowserInfo.js +12 -0
  57. package/client/clientListe/Sortable-master/src/EventDispatcher.js +57 -0
  58. package/client/clientListe/Sortable-master/src/PluginManager.js +87 -0
  59. package/client/clientListe/Sortable-master/src/Sortable.js +1971 -0
  60. package/client/clientListe/Sortable-master/src/utils.js +556 -0
  61. package/client/clientListe/Sortable-master/st/app.js +224 -0
  62. package/client/clientListe/Sortable-master/st/iframe/frame.html +32 -0
  63. package/client/clientListe/Sortable-master/st/iframe/index.html +49 -0
  64. package/client/clientListe/Sortable-master/st/logo.png +0 -0
  65. package/client/clientListe/Sortable-master/st/og-image.png +0 -0
  66. package/client/clientListe/Sortable-master/st/prettify/prettify.css +1 -0
  67. package/client/clientListe/Sortable-master/st/prettify/prettify.js +46 -0
  68. package/client/clientListe/Sortable-master/st/prettify/run_prettify.js +64 -0
  69. package/client/clientListe/Sortable-master/st/saucelabs.svg +1 -0
  70. package/client/clientListe/Sortable-master/st/theme.css +254 -0
  71. package/client/clientListe/Sortable-master/tests/Sortable.compat.test.js +39 -0
  72. package/client/clientListe/Sortable-master/tests/Sortable.test.js +386 -0
  73. package/client/clientListe/Sortable-master/tests/dual-list.html +34 -0
  74. package/client/clientListe/Sortable-master/tests/empty-list.html +30 -0
  75. package/client/clientListe/Sortable-master/tests/filter.html +27 -0
  76. package/client/clientListe/Sortable-master/tests/handles.html +27 -0
  77. package/client/clientListe/Sortable-master/tests/nested.html +67 -0
  78. package/client/clientListe/Sortable-master/tests/single-list.html +25 -0
  79. package/client/clientListe/Sortable-master/tests/style.css +18 -0
  80. package/client/clientListe/clientListe.html +148 -0
  81. package/client/clientListe/clientListe.js +1508 -0
  82. package/client/clientListe/clientListebundle.js +13164 -0
  83. package/client/clientListe/images/poubelle.png +0 -0
  84. package/client/clientListe/images/start.png +0 -0
  85. package/client/clientListe/images/stop.png +0 -0
  86. package/client/clientListe/images/submit.png +0 -0
  87. package/client/clientListe/sortable-theme-bootstrap.css +90 -0
  88. package/client/configurateur/configReact.js +273 -0
  89. package/client/configurateur/configReactbundle.js +295 -0
  90. package/client/configurateur/configurateur.css +95 -0
  91. package/client/configurateur/configurateur.html +48 -0
  92. package/client/configurateur/lib/jexcel.css +755 -0
  93. package/client/configurateur/lib/jexcel.js +14970 -0
  94. package/client/configurateur/lib/jsuites.css +2801 -0
  95. package/client/configurateur/lib/jsuites.js +11822 -0
  96. package/client/configurateur/lib/react-dom.production.min.js +239 -0
  97. package/client/configurateur/lib/react.production.min.js +32 -0
  98. package/client/configurateur/src/configReact.js +247 -0
  99. package/client/controleur/clientcontroleur.js +536 -0
  100. package/client/controleur/clientcontroleur.test.js +282 -0
  101. package/client/controleur/controleur.html +51 -0
  102. package/client/controleur/controleurbundle.js +565 -0
  103. package/client/controleur/stylecontroleur.css +236 -0
  104. package/client/controleurHH/controleurHH.html +71 -0
  105. package/client/controleurHH/controleurHH.js +252 -0
  106. package/client/controleurHH/styles/index.css +320 -0
  107. package/client/controleurHH/styles/material.css +11552 -0
  108. package/client/parametrage/paramReact.js +473 -0
  109. package/client/parametrage/paramReactbundle.js +500 -0
  110. package/client/parametrage/parametrage.css +111 -0
  111. package/client/parametrage/parametrage.html +163 -0
  112. package/client/parametrage/src/paramReact.js +459 -0
  113. package/client/score/hash.js +83 -0
  114. package/client/score/p5.min.js +3 -0
  115. package/client/score/parto1.js +1171 -0
  116. package/client/score/parto1bundle.js +1181 -0
  117. package/client/score/processing.min.js +431 -0
  118. package/client/score/score.html +15 -0
  119. package/client/score/score.js +34 -0
  120. package/client/simulateurListe/simulateurFork.js +750 -0
  121. package/client/simulateurListe/simulateurFork.mjs +681 -0
  122. package/client/simulateurListe/simulateurForkSansReorg.js +569 -0
  123. package/client/simulateurListe/simulateurListe.js +628 -0
  124. package/myReact/archive/Nodeemitvaluedlocal1.hh.js +52 -0
  125. package/myReact/archive/abort-parNode.js +79 -0
  126. package/myReact/archive/abroNode.js +169 -0
  127. package/myReact/archive/abroNode2.js +80 -0
  128. package/myReact/archive/atom.compile.hh.js +51 -0
  129. package/myReact/archive/await-countNode.js +67 -0
  130. package/myReact/archive/await-nowvalNode.js +44 -0
  131. package/myReact/archive/callHH.js +96 -0
  132. package/myReact/archive/emit-if2.hh.compiled.js +113 -0
  133. package/myReact/archive/every1Node.js +35 -0
  134. package/myReact/archive/if-runNode.js +74 -0
  135. package/myReact/archive/if1Node.js +43 -0
  136. package/myReact/archive/makeawait.js +0 -0
  137. package/myReact/archive/myReact.old.js +684 -0
  138. package/myReact/archive/orchestration.js +281 -0
  139. package/myReact/archive/orchestration1.js +132 -0
  140. package/myReact/archive/orchestration1.xml +465 -0
  141. package/myReact/archive/orchestration2.js +161 -0
  142. package/myReact/archive/orchestrationHH.mano.js +280 -0
  143. package/myReact/archive/orchestrationHHTest.js +428 -0
  144. package/myReact/archive/orchestrationHHTest.xml +234 -0
  145. package/myReact/archive/orchestrationHHTestRun.js +104 -0
  146. package/myReact/archive/orchestrationHHTestRun.xml +34 -0
  147. package/myReact/archive/orchestrationTest0.js +178 -0
  148. package/myReact/archive/orchestrationTest1.js +181 -0
  149. package/myReact/archive/orchestrationTest2.js +281 -0
  150. package/myReact/archive/run3pointsNode.js +59 -0
  151. package/myReact/archive/runNode.js +123 -0
  152. package/myReact/archive/runNode2.js +91 -0
  153. package/myReact/archive/testAwait1.js +141 -0
  154. package/myReact/archive/testAwait1.xml +86 -0
  155. package/myReact/archive/testEvery1.js +122 -0
  156. package/myReact/archive/testEvery1.xml +79 -0
  157. package/myReact/archive/testHH1.js +135 -0
  158. package/myReact/archive/testHH1.xml +86 -0
  159. package/myReact/archive/testHH1revu.js +104 -0
  160. package/myReact/archive/testHH2.js +122 -0
  161. package/myReact/archive/testHH2.xml +79 -0
  162. package/myReact/archive/testHH3.js +130 -0
  163. package/myReact/archive/testHH3.xml +86 -0
  164. package/myReact/archive/testHHabort.js +121 -0
  165. package/myReact/archive/testHHabort.xml +83 -0
  166. package/myReact/archive/testMakeawait.js +202 -0
  167. package/myReact/archive/testRun1.js +168 -0
  168. package/myReact/archive/testRun1.xml +142 -0
  169. package/myReact/archive/titi.js +28 -0
  170. package/myReact/archive/titi.xml +110 -0
  171. package/myReact/archive/toto.js +73 -0
  172. package/myReact/archive/toto.xml +198 -0
  173. package/myReact/archive/trap-await-parallelNode.js +123 -0
  174. package/myReact/inutiles/hiver2022.xml +804 -0
  175. package/myReact/inutiles/hopeNode.xml +459 -0
  176. package/myReact/inutiles/mars2022.xml +871 -0
  177. package/myReact/inutiles/mystique1.xml +318 -0
  178. package/myReact/inutiles/mystiqueOSC.xml +277 -0
  179. package/myReact/inutiles/opus5Node.xml +1271 -0
  180. package/myReact/inutiles/opus5NodeLinux.xml +1241 -0
  181. package/myReact/inutiles/orchestrationHH.xml +541 -0
  182. package/myReact/inutiles/orchestrationHH2.xml +547 -0
  183. package/myReact/inutiles/testHH.xml +95 -0
  184. package/myReact/inutiles/trouveLaPercuTenor.xml +349 -0
  185. package/myReact/myReact.js +744 -0
  186. package/myReact/myReact.min.js +1 -0
  187. package/myReact/orchestrationHH.js +311 -0
  188. package/myReact/orchestrationHH.mjs +436 -0
  189. package/myReact/orchestrationHH.mjs.map +1 -0
  190. package/package.json +46 -0
  191. package/serveur/OSCandMidi.mjs +361 -0
  192. package/serveur/computeScore.mjs +415 -0
  193. package/serveur/controleDAW.mjs +1149 -0
  194. package/serveur/defaultSession.csv +2 -0
  195. package/serveur/defaultSkiniParametres.js +119 -0
  196. package/serveur/gameOSC.mjs +96 -0
  197. package/serveur/groupeClientsSons.mjs +1014 -0
  198. package/serveur/ipConfig.json +24 -0
  199. package/serveur/ipConfig127.json +19 -0
  200. package/serveur/ipConfig75.json +17 -0
  201. package/serveur/ipConfigBH.json +19 -0
  202. package/serveur/ipConfigLocal.json +19 -0
  203. package/serveur/midiConfig.json +26 -0
  204. package/serveur/midiConfigBH.json +26 -0
  205. package/serveur/midiConfigVoid.json +3 -0
  206. package/serveur/midimix.mjs +570 -0
  207. package/serveur/saveParam.mjs +159 -0
  208. package/serveur/skiniParametres.good.js +132 -0
  209. package/serveur/skiniParametres.js +106 -0
  210. package/serveur/utilsHHSkini.hh.js +64 -0
  211. package/serveur/utilsSkini.mjs +137 -0
  212. package/serveur/websocketServer.mjs +2052 -0
  213. package/serveur/workerInterfaceZ.mjs +327 -0
  214. package/serveur/workerSynchro.mjs +49 -0
  215. package/skini.mjs +141 -0
@@ -0,0 +1,1508 @@
1
+ /********************************************
2
+
3
+ CODE CLIENT POUR JEU DE TYPE MEMORY MUSICAL
4
+ Sur NODE JS
5
+ © Copyright 2017-2021, B. Petit-Hedelin
6
+
7
+ Utilise:
8
+ https://github.com/SortableJS/Sortable
9
+
10
+ browserify .\clientListe.js -o .\clientListebundle.js
11
+
12
+ ********************************************/
13
+ 'use strict'
14
+
15
+ var ipConfig = require('../../serveur/ipConfig');
16
+ var mr = require('../../myReact/myReact');
17
+
18
+ var $ = require('jquery');
19
+ $('#test').text('browserify working');
20
+
21
+ var par;
22
+ var ws;
23
+
24
+ var idClient = Math.floor((Math.random() * 1000000) + 1); // Pour identifier le client
25
+ var monGroupe = -1; // Fourni par le serveur
26
+ var progCommunication;
27
+ var src = -1; // Pour les fichiers son associés aux patternx
28
+ var DAWON = 0;
29
+ var pseudo;
30
+ var debug = false;
31
+ var debug1 = true;
32
+ var listClips = []; // Devient une array avec toutes les infos sur les clips selectionnes
33
+ var indexChoisi = -1;
34
+ var nombreSonsPossibleInit = 3;
35
+ var nombreSonsPossible = nombreSonsPossibleInit;
36
+ var IdidAChoice = false;
37
+ var groupesDesSons = [];
38
+ var patternsChoisis = []; // Liste des patterns notes Skini de patterns choisis
39
+ var patternsListSent = []; // Liste des patterns qui ont été demandé et dont on attend le jeu
40
+ var initSortableLaunched = false;
41
+
42
+ var sequenceLocale = [];
43
+
44
+ var bleu = "#008CBA";
45
+ var rouge = '#CF1919';
46
+ var vert = "#4CAF50";
47
+ var marron = '#666633';
48
+ var violet = '#797bbf';
49
+ var orange = '#b3712d';
50
+
51
+ navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
52
+
53
+ var english = false;
54
+
55
+ var msg = {
56
+ type: "startSpectateur",
57
+ text: "client",
58
+ id: idClient
59
+ }
60
+
61
+ /*********************************************
62
+
63
+ SECTION NODE
64
+ WEBSOCKET
65
+
66
+ **********************************************/
67
+
68
+ var audioLocal = new Audio();
69
+ var srcInit = "../../sounds/FM8-6.mp3";
70
+ var playPromiseInit;
71
+
72
+ function initWSocket(host) {
73
+ if (host !== undefined) {
74
+ ws = new WebSocket("ws://" + host + ":" + ipConfig.websocketServeurPort); // NODE JS
75
+ console.log("clientListe.js WS://" + host + ":" + ipConfig.websocketServeurPort);
76
+ } else {
77
+ console.log("clientListe.js: initWSSocket host undefined");
78
+
79
+ }
80
+
81
+ ws.onopen = function (event) {
82
+
83
+ var msg = {
84
+ type: "startSpectateur",
85
+ text: "clientListe",
86
+ id: idClient
87
+ }
88
+ ws.send(JSON.stringify(msg));
89
+
90
+ var msg = {
91
+ type: "getPatternGroups",
92
+ }
93
+ try {
94
+ ws.send(JSON.stringify(msg));
95
+ } catch (err) {
96
+ console.log("ERR: onopen getPatternGroups:", err);
97
+ }
98
+
99
+ // Pour la définition de la longueur de la liste de choix
100
+ var msg = {
101
+ type: "getNombreDePatternsPossibleEnListe",
102
+ }
103
+ try {
104
+ ws.send(JSON.stringify(msg));
105
+ } catch (err) {
106
+ console.log("ERR: onopen getNombreDePatternsPossibleEnListe:", err);
107
+ }
108
+ };
109
+
110
+ // ON pourrait peut être mettre ça ailleurs
111
+ setInterval(function () { decrementeAttentes(); }, 1000);
112
+
113
+ //Traitement de la Réception sur le client
114
+ ws.onmessage = function (event) {
115
+ var msgRecu = JSON.parse(event.data);
116
+ //console.log( "Client: received [%s]", event.data );
117
+ //console.log( "Client: received:", msgRecu.type );
118
+
119
+ switch (msgRecu.type) {
120
+
121
+ case "alertInfoScoreON":
122
+ if (debug1) console.log("alertInfoScoreON:", msgRecu.value);
123
+ $('#MessageDuServeur').text(msgRecu.value);
124
+ break;
125
+
126
+ case "alertInfoScoreOFF":
127
+ $('#MessageDuServeur').text(" ");
128
+ break;
129
+
130
+ case "cleanClientChoiceList":
131
+ if (typeof cleanChoiceList == "function") {
132
+ if (msgRecu.group === monGroupe || msgRecu.group === 255) {
133
+ cleanChoiceList();
134
+ }
135
+ }
136
+ break;
137
+
138
+ case "DAWON":
139
+ //Permet de savoir si DAW est actif quand on recharge un client, le serveur envoie l'info à la connexion
140
+ // C'est le même scénario que quand on reçoit un broadcast de "DAWStatus".
141
+ // Version Node JS: est bien utile ?
142
+ DAWON = msgRecu.value;
143
+ if (debug1) console.log("***** reçu message DAWON: ", DAWON);
144
+ actionSurDAWON();
145
+ break;
146
+
147
+ case "DAWStatus":
148
+ if (debug) console.log("Reçu DAWStatus:", msgRecu.value);
149
+ DAWON = msgRecu.value;
150
+ selectAllClips();
151
+
152
+ // On peut recevoir DAWStatus avant d'avoir créer les Listes
153
+ // auquel cas cleanChoiceList n'est pas encore une fonction.
154
+ if (typeof cleanChoiceList == "function") {
155
+ cleanChoiceList();
156
+ initDisplay();
157
+ }
158
+ break;
159
+
160
+ case "delaiInstrument":
161
+ if (debug1) console.log("delayInstrument:delai:", msgRecu.text, "pour son:", msgRecu.son);
162
+ //if ( msgRecu.text != -1) {
163
+ // document.getElementById("sonChoisi").innerHTML = msgRecu.son + " dans " + msgRecu.text + "s";
164
+ //}
165
+ break;
166
+
167
+ case "dureeAttente": // Message en retour d'une demande de jouer un pattern
168
+ afficheAttente(msgRecu.text, msgRecu.son);
169
+ break;
170
+
171
+ case "etatDeLaFileAttente":
172
+ break;
173
+
174
+ case "groupe":
175
+ monGroupe = msgRecu.noDeGroupe;
176
+ if (debug1) console.log("Je suis dans le groupe:", monGroupe);
177
+ if (english) {
178
+ document.getElementById("monGroupe").innerHTML = "In group: " + monGroupe;
179
+ } else {
180
+ document.getElementById("monGroupe").innerHTML = "Mon groupe: " + monGroupe;
181
+ }
182
+ break;
183
+
184
+ case "groupeClientStatus":
185
+ if (debug1) console.log("Reçu Broadcast: groupeClientStatus:", msgRecu, msgRecu.groupeClient);
186
+ if (msgRecu.groupeClient == monGroupe || msgRecu.groupeClient == 255) {
187
+ //if(actionSurGroupeClientPossible) actionSurGroupeClientStatus(retour.groupeName, retour.status);
188
+ actionSurGroupeClientStatus(msgRecu.groupeName, msgRecu.status);
189
+ }
190
+ break;
191
+
192
+ case "infoPlayDAW":
193
+ if (debug1) console.log("Reçu Texte Broadcast infoPlayDAW:", msgRecu);
194
+
195
+ if (msgRecu.value[4] === idClient) { // C'est la position de l'idClient (wsid) dans la file d'attente ([bus, channel, note, velocity, wsid, pseudo, dureeClip, nom]);
196
+ //document.getElementById("MessageDuServeur").textContent = " "; // Nettoyage
197
+ vibration(2000);
198
+ document.body.className = "inplay";
199
+ setTimeout(function () { document.body.className = "black-again" }, 1000);
200
+
201
+ // Retirer le pattern de la liste si c'est un des miens envoyer dans la séquence
202
+ if (debug) console.log("Reçu Texte Broadcast demande de son par pseudo: infoPlayDAW", event.value[7]);
203
+ for (var i = 0; i < patternsListSent.length; i++) {
204
+ if (patternsListSent[i].patternName === msgRecu.value[7]) {
205
+
206
+ mr.activateSignal("infoPlayDAW", 1);
207
+ mr.runProg(progCommunication);
208
+ //communicationMachine.inputAndReact("infoPlayDAW", event.value);
209
+
210
+ patternsListSent.splice(i, 1); // Enlève la position
211
+ if (debug) console.log("Reçu Texte Broadcast demande de son par pseudo: infoPlayDAW: nouvelle liste: ", patternsListSent);
212
+ }
213
+ }
214
+ if (patternsListSent.length === 0) { // On a joué tous les patterns
215
+ if (debug) console.log("Reçu Texte Broadcast demande de son par pseudo: infoPlayDAW: tous les patterns joues");
216
+ mr.activateSignal("receivedAllPatternPlayed", 1);
217
+ mr.runProg(progCommunication);
218
+ //communicationMachine.inputAndReact("receivedAllPatternPlayed");
219
+ if (debug) console.log("Reçu Texte Broadcast demande de son par pseudo: infoPlayDAW: nombreSonsPossible:", nombreSonsPossible);
220
+ }
221
+ }
222
+ break;
223
+
224
+ case "listClips":
225
+ // Réinitialiser l'indicateur de choix réalisé, mécanisme pour potéger des choix répétés
226
+ IdidAChoice = false;
227
+ if (msgRecu.listClips === -1) {
228
+ // if (debug) console.log("WS Recu : listClips: vide", listClips);
229
+ break;
230
+ }
231
+
232
+ // S'il y a des choix et pas que des patterns dans la liste, on n'affiche que les choix
233
+ var listChoice = [];
234
+ for (var i = 0; i < msgRecu.listClips.length; i++) {
235
+ // C'est le code MIDI négatif qui définit un message
236
+ if (msgRecu.listClips[i][0] < 0) {
237
+ msgRecu.listClips[i][11] = 0;
238
+ listChoice.push(msgRecu.listClips[i]);
239
+ }
240
+ }
241
+ if (listChoice.length !== 0) {
242
+ listClips = listChoice; // Pour startClip
243
+ setBoutonSons(listChoice);
244
+ if (debug) console.log("WS Recu : listClips:", msgRecu.listClips);
245
+ break;
246
+ }
247
+
248
+ // A partir d'ici ce sont des patterns
249
+ // Pour conserver les durées d'attente quand la liste est modifiée
250
+ var listClipsNew = [];
251
+ for (var i = 0; i < msgRecu.listClips.length; i++) {
252
+ // Créer une liste intermédiaire à partir de celle reçue
253
+ // avec des durées à 0
254
+ listClipsNew[i] = msgRecu.listClips[i];
255
+ listClipsNew[i][11] = 0;
256
+
257
+ // On balaye la liste en cours en reprenant les durées
258
+ for (var j = 0; j < listClips.length; j++) {
259
+ if (listClips[j][0] == msgRecu.listClips[i][0]) {
260
+ if (listClips[j][11] == undefined) { // Cas initial
261
+ listClips[j][11] = 0;
262
+ }
263
+ listClipsNew[i][11] = listClips[j][11];
264
+ }
265
+ }
266
+ }
267
+
268
+ // On met à jour la liste en cours
269
+ listClips = listClipsNew;
270
+ setBoutonSons(listClips);
271
+ break;
272
+
273
+ case "lesFilesDattente":
274
+ break;
275
+
276
+ case "nombreDePatternsPossible":
277
+ if (debug1) console.log("Reçu Broadcast: nombreDePatternsPossible:", msgRecu.nombreDePatternsPossible);
278
+
279
+ // Protection à l'initilialisation
280
+ if (msgRecu.nombreDePatternsPossible === undefined) break;
281
+
282
+ var nombreDePatternsPossibleEnListe = msgRecu.nombreDePatternsPossible;
283
+
284
+ // Mise à jour du suivi des longueurs de listes d'abord / au groupe
285
+ for (var i = 0; i < nombreDePatternsPossibleEnListe.length; i++) {
286
+ if (nombreDePatternsPossibleEnListe[i][1] === monGroupe) {
287
+ nombreSonsPossibleInit = nombreDePatternsPossibleEnListe[i][0];
288
+ if (debug1) console.log("Reçu Broadcast: nombreDePatternsPossible:nombreSonsPossibleInit ", nombreSonsPossibleInit);
289
+ return;
290
+ }
291
+ } // Sinon en fonction du broadcast 255
292
+ for (var i = 0; i < nombreDePatternsPossibleEnListe.length; i++) {
293
+ if (nombreDePatternsPossibleEnListe[i][1] === 255) {
294
+ nombreSonsPossibleInit = nombreDePatternsPossibleEnListe[i][0];
295
+ if (debug1) console.log("Reçu Broadcast: nombreDePatternsPossible:nombreSonsPossibleInit ", nombreSonsPossibleInit);
296
+ return;
297
+ }
298
+ }
299
+ if (debug1) console.log("nombreDePatternsPossible : ne suis pas concerné : ", msgRecu);
300
+ break;
301
+
302
+ case "message":
303
+ if (debug) console.log(msgRecu.text);
304
+ var element = document.getElementById("MessageDuServeur");
305
+ if (msgRecu.text !== undefined) {
306
+ element.innerHTML = msgRecu.text;
307
+ }
308
+ break;
309
+
310
+ // Donne une liste qui contient la longueur des listes en fonction du groupe
311
+ // dans lequel se trouve le client.
312
+ case "nombreDePatternsPossibleEnListe":
313
+ if (debug1) console.log("socket : nombreDePatternsPossibleEnListe: msgRecu: ", msgRecu.nombreDePatternsPossible);
314
+ var nombreDePatternsPossibleEnListe = msgRecu.nombreDePatternsPossible;
315
+ var flagFin = false;
316
+
317
+ // Mise à jour du suivi des longueurs de listes d'abord / au groupe
318
+ for (var i = 0; i < nombreDePatternsPossibleEnListe.length; i++) {
319
+ if (nombreDePatternsPossibleEnListe[i][1] === monGroupe) {
320
+ nombreSonsPossibleInit = nombreDePatternsPossibleEnListe[i][0];
321
+ nombreSonsPossible = nombreSonsPossibleInit;
322
+ flagFin = true;
323
+ break;
324
+ }
325
+ }
326
+ if (!flagFin) {
327
+ // Sinon en fonction du broadcast 255
328
+ for (var i = 0; i < nombreDePatternsPossibleEnListe.length; i++) {
329
+ if (nombreDePatternsPossibleEnListe[i][1] === 255) {
330
+ nombreSonsPossibleInit = nombreDePatternsPossibleEnListe[i][0];
331
+ nombreSonsPossible = nombreSonsPossibleInit;
332
+ break;
333
+ }
334
+ }
335
+ }
336
+ if (debug1) console.log("Reçu socket : nombreDePatternsPossible:nombreSonsPossibleInit ", nombreSonsPossibleInit);
337
+ break;
338
+
339
+ case "patternSequenceAck":
340
+ mr.activateSignal("patternSequenceAck", msgRecu); // Quid du message reçu ?
341
+ mr.runProg(progCommunication);
342
+ //communicationMachine.inputAndReact("patternSequenceAck", msgRecu);
343
+
344
+ if (english) {
345
+ $('#demandeDeSons').text("My score: " + msgRecu.score);
346
+ } else {
347
+ $('#demandeDeSons').text("Mon score: " + msgRecu.score);
348
+ }
349
+ break;
350
+
351
+ case "setPatternGroups":
352
+ groupesDesSons = msgRecu.value;
353
+ break;
354
+
355
+ case "skiniParametres":
356
+ if (debug1) console.log("skiniParametres:", msgRecu.value);
357
+ par = msgRecu.value;
358
+ break;
359
+
360
+ case "texteServeur":
361
+ if (debug) console.log("Reçu Broadcast:", event.value);
362
+ var element = document.getElementById("Broadcast");
363
+ element.innerHTML = event.value;
364
+ break;
365
+
366
+ case "synchroSkini":
367
+ break;
368
+
369
+ default: console.log("Le Client reçoit un message inconnu", msgRecu);
370
+ }
371
+ };
372
+
373
+ ws.onerror = function (event) {
374
+ console.log("clientmemory.js : received error on WS", ws.socket, " ", event);
375
+ }
376
+
377
+ // Mécanisme de reconnexion automatique si le serveur est tombé.
378
+ // Le service memoryPing permet de vérifier le présence du serveur
379
+ ws.onclose = function (event) {
380
+ DAWON = 0; // Les états sur AbeltonON sont compliqué, cette info est donnée à la connexion.
381
+
382
+ }
383
+ }
384
+ window.initWSocket = initWSocket;
385
+
386
+ function sendPseudo(texte, groupe) {
387
+ msg.type = "clientPseudo";
388
+ msg.pseudo = texte;
389
+ msg.groupe = groupe;
390
+ try {
391
+ ws.send(JSON.stringify(msg));
392
+ } catch (err) {
393
+ console.log("Pb sendPseudo:", err, "\nPseudo: ", texte);
394
+ }
395
+ }
396
+
397
+ /**********************************
398
+
399
+ Automate de communication
400
+
401
+ ***********************************/
402
+
403
+ function makeCommunicationMachine() {
404
+
405
+ mr.createSignal("startTempo", 0);
406
+ mr.createSignal("resetPatternSequenceSent", 0);
407
+ mr.createSignal("alertSequenceOnGoing", 0);
408
+ mr.createSignal("stopListOfPatterns", 0);
409
+ mr.createSignal("resumeListOfPatterns", 0);
410
+ mr.createSignal("sendPatternSequence", 0);
411
+
412
+ // On peut faire des branches de branches
413
+ var instructions = [
414
+ mr._atom(() => { console.log("** Communication automate started"); }),
415
+
416
+ /* mr._every("initialisation",1,
417
+ [
418
+ mr._atom(() => {console.log("** automate: initialisation");}),
419
+ mr._emit("resetPatternSequenceSent", 0),
420
+ mr._await("cleanAllQueues", 1),
421
+ mr._atom( () => {
422
+ console.log("-- cleanQueues");
423
+ cleanChoiceList();
424
+ }),
425
+ mr._emit("resumeListOfPatterns", 0),
426
+ ]
427
+ ),*/
428
+ mr._par(
429
+ [
430
+ mr._loop(
431
+ [
432
+ mr._await("clickPatternSequence", 1),
433
+ mr._atom(() => { console.log("** automate: clickPatternSequence"); }),
434
+ mr._emit("startTempo", 1),
435
+ mr._emit("sendPatternSequence", 1),
436
+ ],
437
+ ),
438
+
439
+ mr._every("infoPlayDAW", 1,
440
+ [
441
+ mr._atom(() => { console.log('** mr: infoPlayDAW'); }),
442
+ ]
443
+ ),
444
+
445
+ mr._every("patternSequenceAck", 1,
446
+ [
447
+ mr._atom(() => { console.log('** mr: patternSequenceAck'); }),
448
+ ]
449
+ ),
450
+ ]
451
+ ),
452
+ mr._atom(() => { console.log("** Communication automate finished"); }),
453
+ ];
454
+
455
+ progCommunication = mr.createModule(instructions);
456
+
457
+ mr.runProg(progCommunication);
458
+ var timeOut;
459
+
460
+ mr.addEventListener("startTempo", function (evt) {
461
+ if (timeOut !== undefined) clearTimeout(timeOut);
462
+ console.log("-- startTempo");
463
+ // Ne devrait pas être nécessaire, on garde en réserve...
464
+ timeOut = setTimeout(function () {
465
+ console.log("-- endTempo");
466
+ }, 15000); // tempo si on ne reçoit pas d'info sur les patterns à jouer
467
+ });
468
+
469
+ mr.addEventListener("resetPatternSequenceSent", function (evt) {
470
+ if (debug1) console.log("-- resetPatternSequenceSent");
471
+ patternsListSent = [];
472
+ });
473
+
474
+ mr.addEventListener("alertSequenceOnGoing", function (evt) {
475
+ if (debug1) console.log("-- alertSequenceOnGoing");
476
+ alert("Séquence en cours");
477
+ });
478
+
479
+ mr.addEventListener("stopListOfPatterns", function (evt) {
480
+ if (debug1) console.log("-- clickOnListOfPatterns");
481
+ actionSurGroupeClientPossible = false;
482
+ });
483
+
484
+ mr.addEventListener("resumeListOfPatterns", function (evt) {
485
+ if (debug1) console.log("-- resumeListOfPatterns");
486
+ actionSurGroupeClientPossible = true;
487
+ });
488
+
489
+ mr.addEventListener("sendPatternSequence", function (evt) {
490
+ if (debug1) console.log("-- sendPatternSequence");
491
+ sequenceLocale = [];
492
+
493
+ if (debug) console.log("sendPatternSequence: patternsChoisis: ", patternsChoisis);
494
+
495
+ if (patternsChoisis.length === 0) {
496
+ console.log("WARN: sendPatternSequence: sequence vide");
497
+ return;
498
+ }
499
+ for (var i = 0; i < patternsChoisis.length; i++) {
500
+ sequenceLocale[i] = patternsChoisis[i].note;
501
+ }
502
+ if (debug1) console.log("-- sendPatternSequence", sequenceLocale);
503
+ msg.type = "sendPatternSequence";
504
+ msg.patternSequence = sequenceLocale;
505
+ msg.pseudo = pseudo;
506
+ msg.groupe = monGroupe;
507
+ msg.idClient = idClient;
508
+ ws.send(JSON.stringify(msg));
509
+
510
+ // Met en place les données pour le mécanisme d'attente
511
+ // du jeu complet de la liste
512
+ patternsListSent = patternsChoisis.slice();
513
+ });
514
+ }
515
+
516
+ /**************************************************
517
+
518
+ Boutons de sélection et d'écoute
519
+
520
+ ***************************************************/
521
+ // Ecoute en local
522
+ function startPlayListe() {
523
+ if (debug1) console.log("startListenClip");
524
+
525
+ document.getElementById("buttonEcouter").style.display = "none";
526
+ document.getElementById("buttonStop").style.display = "inline";
527
+ startSound();
528
+ }
529
+ window.startPlayListe = startPlayListe;
530
+
531
+ // Arret de l'écoute en local
532
+ function stopPlayListe() {
533
+ document.getElementById("buttonEcouter").style.display = "inline";
534
+ document.getElementById("buttonStop").style.display = "none";
535
+ if (audio !== undefined) audio.pause();
536
+ enablePatternChoice();
537
+ }
538
+ window.stopPlayListe = stopPlayListe;
539
+
540
+ var endedListener = null;
541
+ var nextListener = null;
542
+ var audio = new Audio();
543
+
544
+ // startSound remet toute la liste de lecture en place
545
+ // à chaque appel.
546
+ function startSound() {
547
+
548
+ // Protection au départ
549
+ if (patternsChoisis.length === 0) {
550
+ return;
551
+ }
552
+
553
+ var index = 0;
554
+ audio.removeEventListener("error", endedListener);
555
+ audio.removeEventListener("ended", endedListener);
556
+ audio.removeEventListener("ended", nextListener);
557
+
558
+ // Bloque drag and dop
559
+ disablePatternChoice();
560
+
561
+ endedListener = function () {
562
+ if (debug) console.log("play fini");
563
+ index = 0;
564
+ audio.pause();
565
+
566
+ // Remet drag and dop
567
+ enablePatternChoice();
568
+
569
+ // Remet l'affichage en place à la fin de la liste
570
+ document.getElementById("buttonEcouter").style.display = "inline";
571
+ document.getElementById("buttonStop").style.display = "none";
572
+ }
573
+
574
+ nextListener = function () {
575
+ // Le dernier pattern
576
+ if (index == patternsChoisis.length - 1) {
577
+ if (debug) console.log("nextListener:FIN:", index);
578
+ audio.addEventListener("error", endedListener);
579
+ audio.addEventListener("ended", endedListener);
580
+ audio.src = patternsChoisis[index].sound;
581
+ var playPromise = audio.play();
582
+ if (playPromise !== undefined) {
583
+ playPromise.then(function () {
584
+ if (debug) console.log("startSound: nextListener1: Son en cours");
585
+ }).catch(function (error) {
586
+ console.log("WARN: startSound:nextListener1: Erreur Son en cours:", error);
587
+ });
588
+ }
589
+ return;
590
+ } else { // Les autres patterns
591
+ if (debug) console.log("nextListener:index et note:", index, patternsChoisis[index].note);
592
+ audio.addEventListener("error", endedListener);
593
+ audio.addEventListener("ended", nextListener);
594
+ audio.src = patternsChoisis[index].sound;
595
+ var playPromise = audio.play();
596
+ if (playPromise !== undefined) {
597
+ playPromise.then(function () {
598
+ if (debug) console.log("startSound: nextListener2: Son en cours");
599
+ }).catch(function (error) {
600
+ console.log("WARN: startSound:nextListener2: Erreur Son en cours:", error);
601
+ });
602
+ }
603
+ index++;
604
+ }
605
+ }
606
+ nextListener();
607
+ }
608
+
609
+ /****************************************
610
+
611
+ SECTION JS COMPATIBLE NODE.JS
612
+
613
+ *****************************************/
614
+ function vibration(duree) {
615
+ if (navigator.vibrate == undefined) return;
616
+ if ('vibrate' in navigator) {
617
+ navigator.vibrate(duree);
618
+ }
619
+ }
620
+
621
+ //- Attention d'avoir initialisation avant de faire server.addEventListener('DAWStatus', function( event )---
622
+ // Cette fonction de remise à jour de l'affichage est appelée sur plusieurs évènements :
623
+ // onload, Modif DAW, Modif sur groupe de sons, reconnexion, rechargement de la page.
624
+
625
+ $('#monPseudo').keypress(function (e) {
626
+ if (e.which == 13) {
627
+ initialisation();
628
+ }
629
+ });
630
+
631
+ function initDisplay() {
632
+ $('#monPseudo').hide();
633
+ $('#leBoutonPseudo').hide();
634
+ $('#labelSons').text(" ");
635
+ $('#lesProgressBars').show();
636
+ $('#progressbar1').hide();
637
+ $('#progressbar2').hide();
638
+ $('#progressbar3').hide();
639
+ $('#progressbar4').hide();
640
+ $('#progressbar5').hide();
641
+ $('#labelPoubelle').hide();
642
+
643
+ if (DAWON) {
644
+ $('#labelSons').show();
645
+ $('#sonChoisi').show();
646
+ $('#MessageDuServeur').text("");
647
+ $('[class="text-spectacle"]').show();
648
+ $('#listButton').show();
649
+ $('#listButtonChoice').show();
650
+ $('[class="breakAccueil"]').hide();
651
+ $('#labelPoubelle').show();
652
+
653
+ $('#buttonStart').show();
654
+ $('#buttonEcouter').show();
655
+ //listenMachine.inputAndReact("DAWON", true);
656
+ } else {
657
+ $('#labelSons').hide();
658
+ $('#sonChoisi').hide();
659
+ $('#MessageDuServeur').text(pseudo);
660
+ $('[class="text-spectacle"]').hide();
661
+ $('#listButton').hide();
662
+ $('#listButtonChoice').hide();
663
+ $('[class="breakAccueil"]').show();
664
+ $('#labelPoubelle').hide();
665
+
666
+ $('#buttonStart').hide();
667
+ $('#buttonEcouter').hide();
668
+ //listenMachine.inputAndReact("DAWON", false);
669
+ }
670
+ }
671
+
672
+ function initialisation() {
673
+
674
+ makeCommunicationMachine();
675
+
676
+ if (debug) console.log("initialisation:pseudo;", pseudo);
677
+ audioLocal.src = srcInit; // Attention à la création dans la section HOP
678
+ playPromiseInit = audioLocal.play();
679
+
680
+ if (playPromiseInit !== undefined) {
681
+ playPromiseInit.then(function () {
682
+ //if (debug) console.log("Son en cours");
683
+ }).catch(function (error) {
684
+ if (debug) console.log("Erreur Son en cours:", error);
685
+ });
686
+ }
687
+
688
+ // Pour la gestion de la reconnexion si le serveur est tombé et relancé.
689
+ // Si on n'a pas de pseudo en local on suit la procédure de demande d'un pseudo
690
+ // Si on a déjà un pseudo on ne demande rien .
691
+ // La gestion du status du client est dangereuse car c'est document.getElementById("monPseudo").value;
692
+ // qui donne l'état. Ce sera à revoir.
693
+ if (pseudo === undefined) { // Cas de la première fois que l'on appelle le service memory(pseudo)
694
+ var x = $('#monPseudo').val(); // document.getElementById("monPseudo").value;
695
+
696
+ // Protection sur la saisie de messages bizarre et de code
697
+ var regexp = new RegExp('\\W', 'g'); // /\W/g;
698
+ x = x.slice(0, 10).replace(regexp, "");
699
+
700
+ if (x === "" || x === "Votre pseudo") { // Cas du OK sans saisie ou mauvaise saisie
701
+ if (english) {
702
+ $('#MessageDuServeur').text("A pseudo with letters");
703
+ } else {
704
+ $('#MessageDuServeur').text("Un pseudo avec des lettres");
705
+ }
706
+ $('#monPseudo').text("");
707
+ return;
708
+ } else {
709
+ pseudo = x;
710
+ }
711
+ }
712
+ msg.pseudo = pseudo;
713
+
714
+ sendPseudo(pseudo, monGroupe);
715
+
716
+ if (debug1) console.log("clientmemory.js:initialisation: PSEUDO ", pseudo);
717
+
718
+ // Attention: si on envoie un message ici sur la websocket immédiatament après la reconnexion.
719
+ // Il se peut que la socket ne soit pas encore prête. Il y a des choses à faire avec readyState.
720
+
721
+ // On a passé l'étape du pseudo, on peut afficher la page d'interaction
722
+ initDisplay();
723
+
724
+ // Le drag and drop, il ne faut pas le lancer 2 fois
725
+ // ça pertube la gestion des "sort"
726
+ if (!initSortableLaunched) initSortable();
727
+
728
+ // Démarre ou redémarre l'automate de communication
729
+ mr.activateSignal("initialisation", 1);
730
+ mr.runProg(progCommunication);
731
+ //mr.inputAndReact("initialisation");
732
+
733
+ return pseudo;
734
+ }
735
+ window.initialisation = initialisation;
736
+
737
+ // Mettre de l'ordre entre init, initialisation, initWSocket !!
738
+ function init(port, p, unPseudo) {
739
+ if (debug) console.log("init:pseudo=", unPseudo);
740
+ pseudo = unPseudo;
741
+ par = p;
742
+
743
+ if (par.english !== undefined) {
744
+ if (par.english) english = true;
745
+ }
746
+
747
+ //listenMachine = makeListenMachine();
748
+ //communicationMachine = makeCommunicationMachine();
749
+ makeCommunicationMachine();
750
+ initWSSocket(port);
751
+ }
752
+ window.init = init;
753
+
754
+ function decrementeAttentes() {
755
+ for (var i = 0; i < listClips.length; i++) {
756
+ if (listClips[i][11] != 0) {
757
+ listClips[i][11]--;
758
+ var bouton = document.getElementById(i);
759
+ if (bouton !== null) {
760
+ // Affichage de l'attente
761
+ bouton.innerHTML = listClips[i][3].toString() + " " + listClips[i][11].toString() + "s";
762
+ //console.log("----------------attenteInstrument:", listClips[i][3].toString() + " " + listClips[i][11].toString() +"s" );
763
+ }
764
+ }
765
+ }
766
+ }
767
+
768
+ function decreaseProgessBar(progressBar, duree, nomDuSon) {
769
+ // Attention de n'avoir aucun caractère ou CR entre les div des progress bars
770
+ // dans la page HTML. C'est le champ qui est utilisé pour définir si la barre est
771
+ // active.
772
+ if (progressBar.text() === '') {
773
+ $(progressBar).attr("aria-valuenow", duree);
774
+ $(progressBar).text(nomDuSon);
775
+ decreaseProgressBarJQ($(progressBar), nomDuSon);
776
+ return true;
777
+ } else return false;
778
+ }
779
+
780
+ function afficheAttente(duree, nomDuSon) {
781
+ if (duree === 0) {
782
+ if (debug) console.log("afficheAttente: duree 0");
783
+ return;
784
+ }
785
+ if (debug) console.log("---- afficheAttente:text:", $('#progressbar1').text(), ":");
786
+
787
+ if (decreaseProgessBar($('#progressbar1'), duree, nomDuSon)) return;
788
+ if (decreaseProgessBar($('#progressbar2'), duree, nomDuSon)) return;
789
+ if (decreaseProgessBar($('#progressbar3'), duree, nomDuSon)) return;
790
+ if (decreaseProgessBar($('#progressbar4'), duree, nomDuSon)) return;
791
+ if (decreaseProgessBar($('#progressbar5'), duree, nomDuSon)) return;
792
+ console.log("WARN: clientmemory.js: afficheAttente: MESSAGE POUR SON INATTENDU");
793
+ }
794
+
795
+ function decreaseProgressBarJQ(progressBar, nomDuSon) {
796
+ var compte = progressBar.attr("aria-valuenow");
797
+ if (debug) console.log("decreaseProgressBarJQ:compte:", compte);
798
+ progressBar.show();
799
+
800
+ progressBar.text(nomDuSon);
801
+ do {
802
+ setTimeout(function () {
803
+ var attrib = progressBar.attr("aria-valuenow") - 1;
804
+ progressBar.attr("aria-valuenow", attrib);
805
+ progressBar.css("width", attrib.toString() + '%');
806
+
807
+ if (debug) console.log(
808
+ "decreaseProgressBarJQ:", progressBar.text(),
809
+ "setWidth:", attrib.toString() + '%',
810
+ "aria:", progressBar.attr("aria-valuenow"),
811
+ "nombreSonsPossible:", nombreSonsPossible,
812
+ "width:", progressBar.width());
813
+
814
+ if (debug) console.log("Progress value compte JQ:", compte);
815
+ //Il s'agit de prendre en compte la fin d'une demande de pattern
816
+ // en fonction des progress bars et pas du message de broadcast
817
+ // 'infoPlayDAW'.
818
+ // En effet, si on ne reçoit pas le broadcast on reste bloqué.
819
+ if (attrib == 0) {
820
+ progressBar.text('');
821
+ progressBar.hide();
822
+ return;
823
+ }
824
+ }, compte * 1000);
825
+ compte--;
826
+ } while (compte > 0);
827
+ }
828
+
829
+ // Utilisé à partir du broadcast mais aussi du message WS.
830
+ // WS est utilisé en cas de reconnexion.
831
+ function actionSurDAWON() {
832
+ if (DAWON === false) {
833
+ if (debug) console.log("clientmemory.js:actionSurDAWON:false");
834
+ initialisation();
835
+ return;
836
+ } else {
837
+ if (debug) console.log("clientmemory.js:actionSurDAWON:true:", DAWON);
838
+ initialisation(); //Pour le cas où le client recharge sa page en cours d'interaction
839
+ selectAllClips();
840
+ }
841
+ }
842
+
843
+ function actionSurGroupeClientStatus(sons, status) {
844
+ if (DAWON == false) {
845
+ if (debug) console.log("clientmemory.js:actionSurGroupeClientStatus:DAWON:false");
846
+ console.log("initialisation: actionSurGroupeClientStatus");
847
+ initialisation(pseudo);
848
+ return;
849
+ }
850
+
851
+ if (debug) console.log("WS actionSurGroupeClientStatus:", monGroupe);
852
+ selectAllClips();
853
+ }
854
+
855
+ // Gestion de la fermeture du browser
856
+ window.onbeforeunload = function () {
857
+ DAWON = 0; // Réinitialisation
858
+ msg.type = "closeSpectateur";
859
+ msg.text = "DISCONNECT_SPECTATEUR";
860
+ msg.pseudo = pseudo;
861
+ ws.send(JSON.stringify(msg));
862
+ ws.close();
863
+ }
864
+
865
+ /*************************************************
866
+
867
+ Controle des patterns
868
+
869
+ *************************************************/
870
+ function selectAllClips() {
871
+ if (debug1) console.log("selectListClips: monGroupe", monGroupe);
872
+ msg.type = "selectAllClips";
873
+ msg.groupe = monGroupe;
874
+ ws.send(JSON.stringify(msg));
875
+ }
876
+
877
+ // Demande au serveur de lancer le clip
878
+ function startClip() {
879
+
880
+ if (indexChoisi == -1) return -1; // Protection sur un choix sans selection au départ
881
+
882
+ if (nombreSonsPossible < 1) {
883
+ if (english) { document.getElementById("MessageDuServeur").textContent = "You already ask for " + nombreSonsPossibleInit + " pattern."; }
884
+ else { document.getElementById("MessageDuServeur").textContent = "Vous avez dejà demandé " + nombreSonsPossibleInit + " pattern."; }
885
+ return -1;
886
+ }
887
+
888
+ if (debug) console.log("Clip choisi:", listClips[indexChoisi]);
889
+
890
+ // On ne compte pas les messages sans pattern, avec une "note MIDI" négative ce sont des choix
891
+ if (listClips[indexChoisi][0] >= 0) nombreSonsPossible--;
892
+
893
+ if (debug1) {
894
+ if (nombreSonsPossible < 0) console.log("--- !! startclip: nombreSonsPossible = ", nombreSonsPossible);
895
+ }
896
+
897
+ msg.type = "DAWStartClip";
898
+ msg.clipChoisi = listClips[indexChoisi];
899
+ msg.pseudo = pseudo;
900
+ msg.groupe = monGroupe;
901
+ ws.send(JSON.stringify(msg));
902
+
903
+ //document.getElementById("buttonStart").style.backgroundColor = violet; // '#797bbf'
904
+ vibration(200);
905
+
906
+ // On remet le choix en position vide
907
+ // ça évite des bugs sur des choix qui restent en cours
908
+ // ça évite la répétition bête
909
+ indexChoisi = -1;
910
+ document.getElementById("sonChoisi").innerHTML = "";
911
+ }
912
+
913
+ function sendPatternSequence() {
914
+ if (debug1) console.log("sendPatternSequence :", patternsChoisis)
915
+ if (patternsChoisis.length > 0) {
916
+ mr.activateSignal("clickPatternSequence", 1);
917
+ mr.runProg(progCommunication);
918
+ //communicationMachine.inputAndReact("clickPatternSequence");
919
+ }
920
+ }
921
+ window.sendPatternSequence = sendPatternSequence;
922
+
923
+ function getDelayClip() {
924
+ if (indexChoisi == -1) return -1; // Protection sur un choix sans selection au départ
925
+ msg.type = "getDelayInstrument";
926
+ msg.clipChoisi = listClips[indexChoisi];
927
+ msg.pseudo = pseudo;
928
+ msg.groupe = monGroupe;
929
+ ws.send(JSON.stringify(msg));
930
+ }
931
+
932
+ // Ecoute en local
933
+ function startListenClip() {
934
+ //listenMachine.inputAndReact("start", src);
935
+ }
936
+ window.startListenClip = startListenClip;
937
+
938
+ // Arret de l'écoute en local
939
+ function stopListenClip() {
940
+ //listenMachine.inputAndReact("stop");
941
+ }
942
+ window.stopListenClip = stopListenClip;
943
+
944
+ // Pour flasher le smartphone ====================================
945
+ function bg() {
946
+ document.body.className = "inplay";
947
+ setTimeout(function () { document.body.className = "black-again" }, 10);
948
+ }
949
+ exports.bg = bg
950
+
951
+ //========= Automate Buttons de sélection des sons ===============
952
+
953
+ function getSoundFile(nomDuFichierSon) {
954
+
955
+ // Par défaut on a des fichiers sont au format mp3, il faut mettre une extension pour avoir des fichiers wave
956
+ if (DAWON == 1 && par.soundFilesPath1 != undefined && par.soundFilesPath1 != "") {
957
+ if (nomDuFichierSon.includes(".wav")) {
958
+ var nomComplet = "../../sounds/" + par.soundFilesPath1 + "/" + nomDuFichierSon;
959
+ } else {
960
+ var nomComplet = "../../sounds/" + par.soundFilesPath1 + "/" + nomDuFichierSon + ".mp3";
961
+ }
962
+ } else {
963
+ var nomComplet = "../../sounds/" + nomDuFichierSon + ".mp3";
964
+ }
965
+ if (debug1) console.log("getSoundFile: Soundfile recu :", nomComplet);
966
+
967
+ return nomComplet;
968
+ }
969
+
970
+ function getSoundFileNameFromNote(patternsList, noteSKini) {
971
+ for (var i = 0; i < patternsList.length; i++) {
972
+ if (patternsList[i][0] == noteSKini) { // == et pas ===, sinon ça ne marche pas, JS pas typé ?
973
+ return patternsList[i][4]; // Nom du fichier son
974
+ }
975
+ }
976
+ console.log("WARN: getSoundFileNameFromNote: pas de fichier son associé à la note");
977
+ return -1;
978
+ }
979
+
980
+ function getPatternNameFromNote(patternsList, noteSKini) {
981
+ for (var i = 0; i < patternsList.length; i++) {
982
+ if (patternsList[i][0] == noteSKini) { // == et pas ===, sinon ça ne marche pas, JS pas typé ?
983
+ return patternsList[i][3]; // Nom du pattern
984
+ }
985
+ }
986
+ console.log("WARN: getPatternNameFromNote: pas de nom de pattern associé à la note");
987
+ return -1;
988
+ }
989
+
990
+ // Les clips sont des lignes de la table des commandes [4] -> nom du fichier, [3] -> nom du son
991
+ function selectClipBouton(id, listClips) {
992
+
993
+ // Pas utile d'afficher le son choisi dans ce client
994
+ //document.getElementById("sonChoisi").innerHTML = listClips[id][3];
995
+
996
+ indexChoisi = id;
997
+ var nomDuFichierSon = listClips[id][4];
998
+
999
+ // S'il s'agit d'un choix (note MIDI négative), pas besoin de chercher un fichier son et d'envoyer avec le bouton SEND
1000
+ // On envoie tout de suite.
1001
+ if (listClips[id][0] < 0) {
1002
+ if (IdidAChoice) {
1003
+ if (english) { alert("You already did a choice!"); }
1004
+ else { alert("Vous avez déjà fait votre choix!"); }
1005
+ return;
1006
+ }
1007
+
1008
+ startClip();
1009
+
1010
+ if (english) { alert("You choose " + listClips[id][3]); }
1011
+ else { alert("Vous avez choisi " + listClips[id][3]); }
1012
+ IdidAChoice = true;
1013
+ return;
1014
+ }
1015
+
1016
+ // Va chercher le fichier son sur le serveur
1017
+ src = getSoundFile(nomDuFichierSon);
1018
+
1019
+ // Stop le pattern précédent
1020
+ audioLocal.pause();
1021
+
1022
+ // Prépare celui choii
1023
+ audioLocal.src = src;
1024
+
1025
+ // Joue le pattern
1026
+ var playPromise = audioLocal.play();
1027
+
1028
+ if (playPromise !== undefined) {
1029
+ playPromise.then(function () {
1030
+ //if (debug) console.log("Son en cours");
1031
+ }).catch(function (error) {
1032
+ if (debug) console.log("Erreur Son en cours:", error);
1033
+ });
1034
+ }
1035
+
1036
+ getDelayClip(); // Pas utile pour le moment
1037
+ }
1038
+
1039
+ function findColorOfTheGroup(id, listOfgroups) {
1040
+ if (debug) console.log("findColorOfTheGroup:", id, listOfgroups);
1041
+ if (listOfgroups === undefined) return undefined;
1042
+
1043
+ for (var i = 0; i < listOfgroups.length; i++) {
1044
+ if (listOfgroups[i][1] === id) {
1045
+ if (listOfgroups[i][6] !== undefined) return listOfgroups[i][6];
1046
+ }
1047
+ }
1048
+ return undefined;
1049
+ }
1050
+
1051
+ function shuffle(originalArray) {
1052
+ var array = [].concat(originalArray);
1053
+ var currentIndex = array.length, temporaryValue, randomIndex;
1054
+
1055
+ // While there remain elements to shuffle...
1056
+ while (0 !== currentIndex) {
1057
+
1058
+ // Pick a remaining element...
1059
+ randomIndex = Math.floor(Math.random() * currentIndex);
1060
+ currentIndex -= 1;
1061
+
1062
+ // And swap it with the current element.
1063
+ temporaryValue = array[currentIndex];
1064
+ array[currentIndex] = array[randomIndex];
1065
+ array[randomIndex] = temporaryValue;
1066
+ }
1067
+ return array;
1068
+ }
1069
+
1070
+ function setBoutonSons(listOfClipsInit) {
1071
+ var place = document.getElementById("listBoutonsSons");
1072
+ var styleBouton;
1073
+ var colorOfTheClip;
1074
+
1075
+ while (place.firstChild) {
1076
+ place.removeChild(place.firstChild);
1077
+ }
1078
+
1079
+ //tri(listClips, evaluation); // Ce n'est pas ici qu'il faut trier. Il faudrait le faire à chaque reception d'une info
1080
+ // sur une son joué, mais ça fait beaucoup de mouvement dans l'affichage.
1081
+
1082
+ // Les clips sont des lignes de la table des commandes
1083
+ // Table de commandes:
1084
+ // 0= note, 1=note stop, 2=flag, 3=nom, 4=fichier son, 5=instrument, 6=Slot, 7=type, 8=pas utilisé, 9=groupe, 10=durée
1085
+ // 11= réservé client, 12= pseudo
1086
+
1087
+ // Pour certains jeux il faut désorganiser la liste qui suit l'ordre des instruments.
1088
+ // Le classement fourni est bien pour les scénarion DMFN, mais pas pour les jeux où il faut trouver les patterns selon
1089
+ // des instruments, comme c'est naturellement dans l'ordre des instruments c'est trop facile.
1090
+ if (par.shufflePatterns !== undefined) {
1091
+ if (par.shufflePatterns) {
1092
+ var listOfClips = shuffle(listOfClipsInit);
1093
+ } else {
1094
+ var listOfClips = [].concat(listOfClipsInit);
1095
+ }
1096
+ } else {
1097
+ var listOfClips = [].concat(listOfClipsInit);
1098
+ }
1099
+
1100
+ for (var i = 0; i < listOfClips.length; i++) {
1101
+ var bouton = document.createElement("button");
1102
+ bouton.id = i;
1103
+
1104
+ // Si c'est une liste de choix il n'y a pas d'attente à afficher
1105
+ if (listOfClips[i][0] < 0) {
1106
+ bouton.innerHTML = listOfClips[i][3];
1107
+
1108
+ // Les clips sont des lignes de la table des commandes [3] -> nom du son, [11] -> attente
1109
+ } else {
1110
+ bouton.innerHTML = listOfClips[i][3];
1111
+
1112
+ // Avec affichage des attentes, inverser le commentaire avec la ligne précédente
1113
+ // bouton.innerHTML = listOfClips[i][3] + " " + listOfClips[i][11] + "s";
1114
+ }
1115
+ // Pour mettre une couleur selon les instruments
1116
+ // Si dans fichier de configuration [9] -> groupe
1117
+ colorOfTheClip = findColorOfTheGroup(listOfClips[i][9], groupesDesSons);
1118
+
1119
+ if (colorOfTheClip !== undefined) {
1120
+ bouton.style.backgroundColor = colorOfTheClip;
1121
+ } else {
1122
+ console.log("setBoutonSons: couleur non assignée: groupesDesSons", groupesDesSons);
1123
+ var couleur = listOfClips[i][5] % 3; // Palliatif pour faire qqc selon l'instrument en [5]
1124
+ }
1125
+ if (couleur !== undefined) {
1126
+ styleBouton = "boutonsSons " + "boutonsSons" + couleur;
1127
+ } else {
1128
+ styleBouton = "boutonsSons ";
1129
+ }
1130
+ bouton.setAttribute("class", styleBouton);
1131
+
1132
+ bouton.addEventListener("click", function (event) {
1133
+ if (debug1) console.log("click button:id:", this.id);
1134
+ selectClipBouton(this.id, listOfClips);
1135
+ });
1136
+
1137
+ // Il y a un espace dans la liste mais sans clip pour le moment, on ne les affiche pas
1138
+ if (listOfClips[i][3] === '' || listOfClips[i][3] === undefined) {
1139
+ bouton.style.display = "none";
1140
+ }
1141
+
1142
+ // Création d'un champ noteSkini pour les éléments de la liste
1143
+ bouton.dataset.noteSkini = listOfClips[i][0];
1144
+
1145
+ place.appendChild(bouton);
1146
+ }
1147
+ }
1148
+
1149
+ var evaluation = function (a, b) { // Sur les durées
1150
+ return a[11] < b[11];
1151
+ }
1152
+
1153
+ function tri(liste, evaluation) {
1154
+ for (var i = 0; i < liste.length; i++) {
1155
+ // le tableau est trié de 0 à i-1
1156
+ // La boucle interne recherche le min
1157
+ // de i+1 à la fin du tableau.
1158
+ for (var j = i + 1; j < liste.length; j++) {
1159
+ if (evaluation(liste[j], liste[i])) {
1160
+ var temp = liste[j];
1161
+ liste[j] = liste[i];
1162
+ liste[i] = temp;
1163
+ }
1164
+ }
1165
+ }
1166
+ return liste;
1167
+ }
1168
+
1169
+ /*******************************************************
1170
+
1171
+ GESTION DU DRAG AND DROP
1172
+
1173
+ ********************************************************/
1174
+ var disablePatternChoice = null;
1175
+ var enablePatternChoice = null;
1176
+ var cleanChoiceList = null;
1177
+
1178
+ function initSortable() {
1179
+ var sortableChoice;
1180
+ var sortableList;
1181
+
1182
+ disablePatternChoice = function () {
1183
+ sortableChoice.option("disabled", true);
1184
+ sortableList.option("disabled", true);
1185
+ }
1186
+
1187
+ enablePatternChoice = function () {
1188
+ sortableChoice.option("disabled", false);
1189
+ sortableList.option("disabled", false);
1190
+ }
1191
+
1192
+ cleanChoiceList = function () {
1193
+ // Vider les choix en cas de relance de l'automte ou de reconnexion...
1194
+ var place = document.getElementById("patternsChoice");
1195
+ while (place.firstChild) {
1196
+ place.removeChild(place.firstChild);
1197
+ }
1198
+ patternsChoisis = [];
1199
+ nombreSonsPossible = nombreSonsPossibleInit;
1200
+ sortableChoice.option("disabled", false);
1201
+ sortableList.option("disabled", false);
1202
+
1203
+ if (debug1) console.log("cleanChoiceList:nombreSonsPossible:", nombreSonsPossible);
1204
+ }
1205
+
1206
+ sortableList = new Sortable(listBoutonsSons, {
1207
+ group: {
1208
+ name: 'listBoutonsSons',
1209
+ pull: 'clone'
1210
+ //put: ['patternsChoice']
1211
+ },
1212
+
1213
+ put: false, // Do not allow items to be put into this list, ne fonctionne pas
1214
+ //group: 'shared',
1215
+ animation: 150,
1216
+ sort: false, // To disable sorting: set sort to false
1217
+ delay: 100, // Pour permettre le click sur un bouton sur Android
1218
+ disabled: false, // nécessaire mais pas dans la doc. Ceci bloque bien la liste, à true.
1219
+
1220
+ onStart: function (evt) {
1221
+ if (debug) console.log("onstart:", evt.oldIndex);
1222
+ mr.activateSignal("receivedAllPatternPlayed", 1);
1223
+ mr.runProg(progCommunication);
1224
+ //communicationMachine.inputAndReact("clickOnListOfPatterns");
1225
+ },
1226
+
1227
+ onChoose: function (evt) {
1228
+ if (debug) console.log("onChoose:", evt.oldIndex);
1229
+ mr.activateSignal("clickOnListOfPatterns", 1);
1230
+ mr.runProg(progCommunication);
1231
+ //communicationMachine.inputAndReact("clickOnListOfPatterns");
1232
+ },
1233
+
1234
+ onMove: function (evt) {
1235
+ if (debug1) console.log("onMove");
1236
+ mr.activateSignal("clickOnListOfPatterns", 1);
1237
+ mr.runProg(progCommunication);
1238
+ //communicationMachine.inputAndReact("clickOnListOfPatterns");
1239
+ },
1240
+
1241
+ // Element dragging ended
1242
+ onEnd: function (evt) {
1243
+ if (debug1) console.log("sortableList: on End");
1244
+ //if(debug1) console.log("listBoutonsSons: onEnd: Old",evt.oldIndex, ": new: ", evt.newIndex);
1245
+ var itemEl = evt.item; // dragged HTMLElement
1246
+ evt.to; // target list
1247
+ evt.from; // previous list
1248
+ evt.oldIndex; // element's old index within old parent
1249
+ evt.newIndex; // element's new index within new parent
1250
+ //evt.oldDraggableIndex; // element's old index within old parent, only counting draggable elements
1251
+ //evt.newDraggableIndex; // element's new index within new parent, only counting draggable elements
1252
+ evt.clone; // the clone element
1253
+ //evt.pullMode; // when item is in another sortable: `"clone"` if cloning, `true` if moving
1254
+
1255
+ if (debug1) console.log("listBoutonsSons: onEnd: Old", evt.oldIndex, ": new: ", evt.newIndex, "\n", listBoutonsSons);
1256
+
1257
+ // sort : false et put: false ne fonctionnent pas
1258
+ // Je contourne le pb de put en ne faisant rien quand on bouge un patterns dans la liste de boutons sons
1259
+ if (debug1) console.log("listBoutonsSons: onEnd: evt.to;", evt.to.id);
1260
+ if (evt.to.id === "listBoutonsSons") {
1261
+ if (debug1) console.log("listBoutonsSons: onEnd: sort: ", sortableList);
1262
+ return;
1263
+ }
1264
+
1265
+ if (nombreSonsPossible <= 0) {
1266
+ if (debug1) console.log("sortable: sortableList: onEnd: plus de pattern possible:", nombreSonsPossible);
1267
+
1268
+ $('#messageAlert').show();
1269
+ if (english) {
1270
+ $('#messageAlert').text("Your reach the max of patterns");
1271
+ } else {
1272
+ $('#messageAlert').text("Max de patterns atteint");
1273
+ }
1274
+
1275
+ setTimeout(() => { $('#messageAlert').hide(); }, 3000);
1276
+ //alert("Max de clip atteint");
1277
+
1278
+ sortableList.option("disabled", true); // Ne fonctionne pas ici ?
1279
+
1280
+ // On enlève le dernier élément déposé car il a déjà été pris en compte
1281
+ // par sortableChoice quand on arrive ici
1282
+ var itemEl = evt.item; // dragged HTML Element
1283
+ itemEl.parentNode.removeChild(itemEl); // Suppression de l'élément
1284
+ patternsChoisis.splice(evt.newIndex, 1);
1285
+ } else {
1286
+ nombreSonsPossible--;
1287
+ if (debug1) console.log("sortableList: on End: nombreSonsPossible", nombreSonsPossible);
1288
+ }
1289
+ },
1290
+
1291
+ // Element is dropped into the list from another list
1292
+ onAdd: function (evt) {
1293
+ if (debug) console.log("listBoutonsSons: onAdd: Old", evt.oldIndex, ": new: ", evt.newIndex);
1294
+ if (debug1) console.log("listBoutonsSons: onAdd: nombreSonsPossible", nombreSonsPossible);
1295
+ // same properties as onEnd
1296
+ },
1297
+
1298
+ // Changed sorting within list
1299
+ onUpdate: function (evt) {
1300
+ if (debug1) console.log("listBoutonsSons: onUpdate: Old", evt.oldIndex, ": new: ", evt.newIndex);
1301
+ // same properties as onEnd
1302
+ },
1303
+
1304
+ // Called when creating a clone of element
1305
+ // Ceci est nécessaire car on perd les events avec le clonage
1306
+ onClone: function (evt) {
1307
+ if (debug) console.log("On Clone liste de clip reçue");
1308
+ evt.clone.addEventListener("click", function (event) {
1309
+ if (debug) console.log("click button:id:", this.id, listClips);
1310
+ selectClipBouton(this.id, listClips);
1311
+ });
1312
+ }
1313
+ });
1314
+
1315
+ sortableChoice = new Sortable(patternsChoice, {
1316
+ group: {
1317
+ name: 'patternsChoice',
1318
+ put: ['listBoutonsSons']
1319
+ },
1320
+ animation: 150,
1321
+ sort: true, // To disable sorting: set sort to false
1322
+ disabled: false, // nécessaire ? mais pas dans la doc. Inopérant sur cette liste.
1323
+ delay: 100, // Pour permettre le click sur un bouton sur Android
1324
+
1325
+ // Element dragging ended
1326
+ onEnd: function (evt) {
1327
+ var itemEl = evt.item; // dragged HTMLElement
1328
+ evt.to; // target list
1329
+ evt.from; // previous list
1330
+ evt.oldIndex; // element's old index within old parent
1331
+ evt.newIndex; // element's new index within new parent
1332
+ evt.oldDraggableIndex; // element's old index within old parent, only counting draggable elements
1333
+ evt.newDraggableIndex; // element's new index within new parent, only counting draggable elements
1334
+ evt.clone // the clone element
1335
+ evt.pullMode; // when item is in another sortable: `"clone"` if cloning, `true` if moving
1336
+
1337
+ var noteSkini = evt.clone.getAttribute("data-note-skini");
1338
+ if (noteSkini === undefined) {
1339
+ console.log("ERR: Sortable: patternsChoice: onEnd: noteSkini undefined");
1340
+ } else {
1341
+ if (debug) console.log("Sortable: patternsChoice: onEnd: noteSkini:", noteSkini, evt.newIndex, patternsChoisis);
1342
+ }
1343
+
1344
+ // On ne prend pas en compte la réorganisation de la liste pour le décompte
1345
+ if (debug1) console.log("patternsChoice: onEnd: evt.to;", evt.to.id);
1346
+ if (evt.to.id === "patternsChoice") {
1347
+ return;
1348
+ } else if (evt.to.id === "poubelle") {
1349
+ nombreSonsPossible++;
1350
+ }
1351
+ if (debug1) console.log("Sortable: patternsChoice: onEnd: après nombreSonsPossible:", nombreSonsPossible);
1352
+ },
1353
+
1354
+ // Element is dropped into the list from another list
1355
+ onAdd: function (evt) {
1356
+ //console.log("Right On Add", evt.from, ":", evt.to, ":",evt.oldIndex, ":", evt.newIndex);
1357
+ //console.log("Choice On Add: Old",evt.oldIndex, ": new: ", evt.newIndex, evt.clone);
1358
+ // same properties as onEnd
1359
+
1360
+ mr.activateSignal("onAddPattern", evt.oldIndex);
1361
+ mr.runProg(progCommunication);
1362
+ //communicationMachine.inputAndReact("onAddPattern", evt.oldIndex);
1363
+
1364
+ if (debug) console.log("sortable: patternsChoice: onAdd 2 :", nombreSonsPossible);
1365
+
1366
+ var noteSkini = evt.clone.getAttribute("data-note-skini");
1367
+ if (noteSkini === undefined) {
1368
+ console.log("ERR: Sortable: patternsChoice: onAdd:noteSkini undefined");
1369
+ } else {
1370
+ var selectedPattern = new Object();
1371
+ selectedPattern.note = noteSkini;
1372
+ var fileName = getSoundFileNameFromNote(listClips, noteSkini);
1373
+ var patternName = getPatternNameFromNote(listClips, noteSkini);
1374
+ if (fileName !== -1 && patternName !== -1) {
1375
+ selectedPattern.sound = getSoundFile(fileName);
1376
+ selectedPattern.patternName = patternName;
1377
+ patternsChoisis.splice(evt.newIndex, 0, selectedPattern); // Insére le pattern
1378
+ if (debug) console.log("Sortable: patternsChoice: onAdd: noteSkini:", noteSkini, nombreSonsPossible, patternsChoisis);
1379
+ // Il faut regénerer l'automate avec la nouvelle liste
1380
+ // makeListenMachine(); // !!!
1381
+ } else {
1382
+ console.log("WARN: sortableChoice: onAdd: note no more in the list of patterns");
1383
+ }
1384
+ }
1385
+ },
1386
+
1387
+ // Changed sorting within list
1388
+ onUpdate: function (evt) {
1389
+ if (debug1) console.log("sortableChoice: On Update");
1390
+ //console.log("Right OnUpdate", evt.from, ":", evt.to, ":",evt.oldIndex, ":", evt.newIndex);
1391
+ if (debug) console.log("Choice onUpdate: Old", evt.oldIndex, ": new: ", evt.newIndex, evt.clone);
1392
+ // same properties as onEnd
1393
+
1394
+ var noteSkini = evt.clone.getAttribute("data-note-skini");
1395
+ if (noteSkini === undefined) {
1396
+ console.log("ERR: Sortable: patternsChoice: onUpdate: noteSkini undefined");
1397
+ } else {
1398
+ if (patternsChoisis.length > 0) {
1399
+ patternsChoisis.splice(evt.oldIndex, 1); // Enlève l'ancienne position
1400
+
1401
+ var selectedPattern = new Object();
1402
+ selectedPattern.note = noteSkini;
1403
+ var fileName = getSoundFileNameFromNote(listClips, noteSkini);
1404
+ var patternName = getPatternNameFromNote(listClips, noteSkini);
1405
+ if (fileName !== -1 && patternName !== -1) {
1406
+ selectedPattern.sound = getSoundFile(fileName);
1407
+ selectedPattern.patternName = patternName;
1408
+ patternsChoisis.splice(evt.newIndex, 0, selectedPattern); // Insére à la nouvelle position
1409
+
1410
+ // Il faut regénerer l'automate avec la nouvelle liste
1411
+ //makeListenMachine();
1412
+
1413
+ } else {
1414
+ console.log("WARN: sortableChoice: onUpdate: note no more in the list of patterns");
1415
+ }
1416
+ }
1417
+ if (debug) console.log("Sortable: patternsChoice: onUpdate: noteSkini:", noteSkini, evt.newIndex, patternsChoisis);
1418
+ }
1419
+ },
1420
+
1421
+ // Event when you move an item in the list or between lists
1422
+ onMove: function (evt) {
1423
+ if (debug1) console.log("sortableChoice: On Move");
1424
+ },
1425
+
1426
+ // Called when creating a clone of element
1427
+ onClone: function (evt) {
1428
+ if (debug1) console.log("sortableChoice: On onClone");
1429
+ }
1430
+ });
1431
+
1432
+ new Sortable(poubelle, {
1433
+ group: {
1434
+ name: 'poubelle',
1435
+ //pull: false,
1436
+ put: ['patternsChoice']
1437
+ },
1438
+ animation: 150,
1439
+
1440
+ // Element dragging ended
1441
+ onEnd: function (evt) {
1442
+ var itemEl = evt.item; // dragged HTMLElement
1443
+ evt.to; // target list
1444
+ evt.from; // previous list
1445
+ evt.oldIndex; // element's old index within old parent
1446
+ evt.newIndex; // element's new index within new parent
1447
+ evt.oldDraggableIndex; // element's old index within old parent, only counting draggable elements
1448
+ evt.newDraggableIndex; // element's new index within new parent, only counting draggable elements
1449
+ evt.clone // the clone element
1450
+ evt.pullMode; // when item is in another sortable: `"clone"` if cloning, `true` if moving
1451
+
1452
+ var noteSkini = evt.clone.getAttribute("data-note-skini");
1453
+ if (noteSkini === undefined) {
1454
+ console.log("ERR: Sortable:poubelle: onEnd:noteSkini undefined");
1455
+ } else {
1456
+ if (debug) console.log("Sortable: poubelle: onEnd:noteSkini:", noteSkini, evt.newIndex);
1457
+ }
1458
+ },
1459
+
1460
+ // Element is dropped into the list from another list
1461
+ onAdd: function (evt) {
1462
+ //console.log("Right On Add", evt.from, ":", evt.to, ":",evt.oldIndex, ":", evt.newIndex);
1463
+ //console.log("poubelle On Add: Old",evt.oldIndex, ": new: ", evt.newIndex, evt.clone);
1464
+ //sortableChoice.option("disabled", false);
1465
+
1466
+ if (debug1) console.log("poubelle On Add: nombreSonsPossible: ", nombreSonsPossible);
1467
+ sortableList.option("disabled", false);
1468
+
1469
+ var noteSkini = evt.clone.getAttribute("data-note-skini");
1470
+ if (noteSkini === undefined) {
1471
+ console.log("ERR: Sortable:poubelle: onAdd: noteSkini undefined");
1472
+ } else {
1473
+ patternsChoisis.splice(evt.oldIndex, 1);
1474
+ if (debug) console.log("Sortable: poubelle: onAdd: noteSkini:", noteSkini, nombreSonsPossible, patternsChoisis);
1475
+
1476
+ // Quand la liste des choix est vide on réinitialise le compteur
1477
+ if (patternsChoisis.length === 0) {
1478
+ nombreSonsPossible = nombreSonsPossibleInit - 1; // -1 car Pb d'index et de nombre...
1479
+ }
1480
+
1481
+ // Il faut regénerer l'automate avec la nouvelle liste
1482
+ //makeListenMachine();
1483
+ }
1484
+
1485
+ // same properties as onEnd
1486
+ var itemEl = evt.item; // dragged HTML Element
1487
+ itemEl.parentNode.removeChild(itemEl); // Suppression de l'élément
1488
+ },
1489
+
1490
+ // Changed sorting within list
1491
+ onUpdate: function (evt) {
1492
+ //console.log("Right OnUpdate", evt.from, ":", evt.to, ":",evt.oldIndex, ":", evt.newIndex);
1493
+ //console.log("poubelle onUpdate: old ",evt.oldIndex, ": new: ", evt.newIndex);
1494
+
1495
+ var noteSkini = evt.clone.getAttribute("data-note-skini");
1496
+ if (noteSkini === undefined) {
1497
+ console.log("ERR: Sortable:poubelle: onUpdate: noteSkini undefined");
1498
+ } else {
1499
+ if (debug) console.log("Sortable: poubelle: onUpdate: noteSkini:", noteSkini, evt.oldIndex);
1500
+ }
1501
+ // same properties as onEnd
1502
+ }
1503
+ });
1504
+
1505
+ if (cleanChoiceList !== null) cleanChoiceList();
1506
+
1507
+ initSortableLaunched = true;
1508
+ }