Browse Source

update display of calibration every n scenes

Jérôme BUISINE 10 months ago
parent
commit
f748ffd206

+ 1 - 0
src/components/ExperimentBlock.vue

@@ -16,6 +16,7 @@
           -->
 
           <h2 v-if="runExpe === true">"{{ $route.meta.fullName }}"</h2>
+
           <!-- <h3>{{ sceneName }}</h3> -->
 
           <slot name="header"></slot>

+ 6 - 1
src/mixins/ExperimentBase.vue

@@ -31,6 +31,11 @@ export default {
     ...mapGetters(['getHostURI', 'getExperimentProgress', 'isExperimentDone'])
   },
   mounted() {
+    // here push in session (if not already there) current user advancement
+    if (window.sessionStorage.getItem('sin3d-nb-scenes') === null) {
+      window.sessionStorage.setItem('sin3d-nb-scenes', 0)
+    }
+
     if (!this.getExperimentProgress({ experimentName: this.experimentName, sceneName: this.sceneName }).experimentName)
       this.sendMessage({
         msgId: experimentMsgId.STARTED,
@@ -41,7 +46,7 @@ export default {
       })
 
     // Check if the experiment is already finished
-    if (this.experimentName && this.sceneName && this.isExperimentDone({ experimentName: this.experimentName, sceneName: this.sceneName })) {
+    if (this.experimentName && this.sceneName && this.isExperimentDone({ experimentName: this.experimentName, sceneName: this.sceneName }) && this.sceneName !== '50_shades_of_grey') {
       console.warn('Redirected from experiment. You can\'t go back in an experiment after finishing it.')
       this.$router.push(`/experiments/${this.experimentName}`)
     }

+ 20 - 6
src/mixins/ExperimentBaseExtracts.vue

@@ -26,7 +26,9 @@ export default {
 
       showHoverBorder: null,
       lockConfig: null,
-      comment: null
+      comment: null,
+      dialogMore: false,
+      dialogLess: false
     }
   },
   computed: {
@@ -116,11 +118,13 @@ export default {
       const qualityIndex = this.qualities.indexOf(quality)
       let action, newQuality
 
-      if (event.button === 0) action = 'needLess' // Left click
-      if (event.button === 2) action = 'needMore' // Right click
+      console.log(qualityIndex)
 
-      if (event.button === 0 && event.ctrlKey) action = 'need10Less' // ctrl + Right click
-      if (event.button === 2 && event.ctrlKey) action = 'need10More' // ctrl + Left click
+      if (event.button === 0) action = 'needMore' // Left click
+      if (event.button === 2) action = 'needLess' // Right click
+
+      if (event.button === 0 && event.ctrlKey) action = 'need10More' // ctrl + Right click
+      if (event.button === 2 && event.ctrlKey) action = 'need10Less' // ctrl + Left click
 
       if (action === 'needLess') newQuality = precQuality
       if (action === 'needMore') newQuality = nextQuality
@@ -140,7 +144,17 @@ export default {
       }
 
       // Do not load a new extract if same quality
-      if (newQuality === quality) return
+      if (newQuality === quality) {
+        // display alert once limit is reached
+        if (action === 'needLess' || action === 'need10Less') {
+          this.dialogLess = true
+        }
+        if (action === 'needMore' || action === 'need10More') {
+          this.dialogMore = true
+        }
+
+        return
+      }
 
       // Set loading state
       this.extracts[index].loading = true

+ 2 - 2
src/router/experiments.js

@@ -5,7 +5,7 @@ export default [
     component: () => import('@/views/Experiments/MatchExtractsWithReference'),
     props: true,
     meta: {
-      fullName: 'Cliquer sur les zones de l\'image de gauche (clic droit de la souris)  afin de la faire correspondre à celle de droite'
+      fullName: 'Cliquer sur les zones de l\'image de gauche (clic gauche de la souris)  afin de la faire correspondre à celle de droite'
       // fullName: 'Match extracts qualities to reference image'
     }
   },
@@ -69,7 +69,7 @@ export default [
     component: () => import('@/views/Experiments/CalibrationMeasurement'),
     props: true,
     meta: {
-      fullName: 'Cliquer sur les zones de l\'image de gauche (clic droit de la souris)  afin de faire correspondre la teinte à celle de droite'
+      fullName: 'Cliquer sur les zones de l\'image de gauche (clic gauche de la souris)  afin de faire correspondre la teinte à celle de droite'
     }
   }
 ]

+ 27 - 6
src/views/ExperimentValidated.vue

@@ -28,7 +28,9 @@
       </v-card-actions>
     </v-card> -->
 
-    <div style="margin-top:10%">
+    <loader v-if="!loaded" :message="loadingMessage" />
+
+    <div v-if="loaded" style="margin-top:10%">
       <p style="font-size: 1.4em;">
         Nous vous remercions d'avoir participé à cette expérience.
         Elle va nous permettre d'améliorer les calculs d'images.
@@ -36,11 +38,12 @@
     </div>
 
     <!-- Add of newsletter component -->
-    <Newsletter />
+    <Newsletter v-if="loaded" />
   </div>
 </template>
 
 <script>
+import Loader from '@/components/Loader.vue'
 import { mapActions, mapGetters } from 'vuex'
 import Experiments from '@/router/experiments'
 import { getExperimentSceneList } from '@/config.utils'
@@ -50,7 +53,8 @@ import Newsletter from '@/components/ExperimentsComponents/Newsletter.vue'
 export default {
   name: 'ExperimentValidated',
   components: {
-    Newsletter
+    Newsletter,
+    Loader
   },
   props: {
     experimentName: {
@@ -65,7 +69,10 @@ export default {
   data() {
     return {
       experimentFullName: null,
-      availableScenes: []
+      availableScenes: [],
+      showCalibrationEvery: 5,
+      loaded: false,
+      loadingMessage: 'Chargement...'
     }
   },
   computed: {
@@ -98,9 +105,23 @@ export default {
         this.progression[this.experimentName] &&
         !this.progression[this.experimentName][aScene].done)
 
-    if (this.hasScenesLeft) {
-      this.$router.push(`/experiments/${this.experimentName}/${this.getRandomScene}`)
+    // check if necessary to show calibration before new scenes
+    if (window.sessionStorage.getItem('sin3d-nb-scenes') !== null) {
+      let nScenes = Number(window.sessionStorage.getItem('sin3d-nb-scenes'))
+      window.sessionStorage.setItem('sin3d-nb-scenes', nScenes + 1)
+
+      console.log('Check ', nScenes, ' => ', this.showCalibrationEvery)
+
+      if (nScenes % this.showCalibrationEvery === 0) {
+        console.log('Start redirect to calibration')
+        this.$router.push(`/experiments/${this.experimentName}/50_shades_of_grey`)
+      }
+      else if (this.hasScenesLeft) {
+        this.$router.push(`/experiments/${this.experimentName}/${this.getRandomScene}`)
+      }
     }
+
+    this.loaded = true
   }
 }
 </script>

+ 182 - 31
src/views/Experiments/MatchExtractsWithReference.vue

@@ -1,6 +1,7 @@
 <template>
   <ExperimentBlock
     :run-expe="runExpe"
+    :calibration-check="calibrationCheck"
     :experiment-name="experimentName"
     :scene-name="sceneName"
     :loading-message="loadingMessage"
@@ -18,6 +19,128 @@
     </template>
 
     <template v-slot:content>
+      <div class="text-center">
+        <v-dialog
+          v-model="dialogLess"
+          v-if="explanation === false"
+          width="500"
+        >
+          <v-card>
+            <v-card-title
+              class="headline lighten-2"
+              primary-title
+            >
+              <p style="font-size:0.8em;">La qualité de cette zone est déjà à son <strong>minimum</strong></p>
+            </v-card-title>
+
+            <v-divider />
+
+            <v-card-actions>
+              <v-spacer />
+              <v-btn
+                color="primary"
+                text
+                @click="dialogLess = false"
+              >
+                Fermer
+              </v-btn>
+            </v-card-actions>
+          </v-card>
+        </v-dialog>
+      </div>
+      <div class="text-center">
+        <v-dialog
+          v-model="dialogMore"
+          v-if="explanation === false"
+          width="500"
+        >
+          <v-card>
+            <v-card-title
+              class="headline lighten-2"
+              primary-title
+            >
+              <p style="font-size:0.8em;">La qualité de cette zone est déjà à son <strong>maximum</strong></p>
+            </v-card-title>
+
+            <v-divider />
+
+            <v-card-actions>
+              <v-spacer />
+              <v-btn
+                color="primary"
+                text
+                @click="dialogMore = false"
+              >
+                Fermer
+              </v-btn>
+            </v-card-actions>
+          </v-card>
+        </v-dialog>
+      </div>
+      <div class="text-center">
+        <v-dialog
+          v-model="dialogRefError"
+          v-if="explanation === false"
+          width="600"
+        >
+          <v-card>
+            <v-card-title
+              class="headline lighten-2"
+              primary-title
+            >
+              <p style="font-size:0.8em;">
+                Vous venez de cliquer sur l'image de référence. Celle-ci ne sera pas modifiée par cette action. <br /><br />
+                L'expérience a pour objectif de régler la qualité de l'image de gauche pour qu'elle soit la plus proche de l'image de droite.
+              </p>
+            </v-card-title>
+
+            <v-divider />
+
+            <v-card-actions>
+              <v-spacer />
+              <v-btn
+                color="primary"
+                text
+                @click="dialogRefError = false"
+              >
+                Fermer
+              </v-btn>
+            </v-card-actions>
+          </v-card>
+        </v-dialog>
+      </div>
+      <div class="text-center">
+        <v-dialog
+          v-model="calibrationCheck"
+          width="600"
+        >
+          <v-card>
+            <v-card-title
+              class="headline lighten-2"
+              primary-title
+            >
+              <p style="font-size:0.8em;">
+                La scène de calibration vous est proposée de nouveau dans le but de vérifier que l'image de gauche correspond toujours à celle de droite sur votre écran actuel.
+                <br /><br />
+                Vous pouvez la régler de nouveau si cela est nécessaire.
+              </p>
+            </v-card-title>
+
+            <v-divider />
+
+            <v-card-actions>
+              <v-spacer />
+              <v-btn
+                color="primary"
+                text
+                @click="calibrationCheck = false"
+              >
+                Fermer
+              </v-btn>
+            </v-card-actions>
+          </v-card>
+        </v-dialog>
+      </div>
       <v-flex v-if="explanation === true || disableStart === true" xs12 sm12>
         <div style="margin-top:10%">
           <p v-if="disableStart === false && calibrationScene === true" style="font-size: 1.4em;">
@@ -55,11 +178,11 @@
           <br />
 
           <p style="font-size: 1.4em;text-align:left">
-            Pour cela deux actions vous sont proposées :
+            Pour cela, deux actions vous sont proposées :
             <br />
             <ul>
-              <li> <strong>clic droit de la souris :</strong> permet d'améliorer la qualité de l'image à l'endroit où de la dégradation vous est encore visible.</li>
-              <li> <strong>clic gauche de la souris :</strong> permet de revenir à une qualité inférieure de l'image si l'amélioration apportée n'était pas nécessaire (aucune amélioration visible apportée après clic droit).</li>
+              <li> <strong>clic gauche de la souris :</strong> permet d'améliorer la qualité de l'image à l'endroit où de la dégradation vous est encore visible.</li>
+              <li> <strong>clic droit de la souris :</strong> permet de revenir à une qualité inférieure de l'image si l'amélioration apportée n'était pas nécessaire (aucune amélioration visible apportée après clic droit).</li>
             </ul>
           </p>
 
@@ -125,7 +248,7 @@
           </v-container>
         </v-card>
       </v-flex>
-      <v-flex v-if="runExpe === true" sm6 xs12 :style="{ 'max-width': maxWidth + 'px', 'min-width': maxWidth + 'px' }">
+      <v-flex @click="dialogRefError = true" v-if="runExpe === true" sm6 xs12 :style="{ 'max-width': maxWidth + 'px', 'min-width': maxWidth + 'px' }">
         <v-card dark color="primary" :max-width="maxWidth" :min-width="maxWidth">
           <!-- <v-card-text>Reference image</v-card-text> -->
           <v-img v-if="referenceImage" :src="referenceImage" :max-height="maxHeight" :max-width="maxWidth" :min-width="maxWidth" />
@@ -143,7 +266,7 @@
 
         <v-btn @click="userBreak" color="#cc7a00" large right>Arrêter ou faire une pause</v-btn>
 
-        <v-btn @click="finishExperiment" color="success" large right>Valider & passer à l'image suivante</v-btn>
+        <v-btn @click="finishExperiment" color="#008000" large right>Valider & passer à l'image suivante</v-btn>
       </v-layout>
       <!--/ Experiment validation button -->
     </template>
@@ -177,47 +300,75 @@ export default {
       haveHelp: false,
       calibrationScene: false,
       runExpe: false,
-      disableStart: false
+      calibrationCheck: false,
+      disableStart: false,
+      dialogRefError: false
     }
   },
   computed: {
-    ...mapGetters(['getHostURI'])
+    ...mapGetters(['getHostURI', 'getAllExperimentProgress'])
   },
   async mounted() {
-    // Load config for this scene to local state
-    this.loadConfig()
+    // redirect by default to calibration scene
+    let nScenes = Number(window.sessionStorage.getItem('sin3d-nb-scenes'))
+    if (nScenes === 0) {
+      console.log('number of scene is', nScenes)
+      window.sessionStorage.setItem('sin3d-nb-scenes', nScenes + 1)
+      this.$router.push(`/experiments/${this.experimentName}/50_shades_of_grey`)
+    }
+    else {
+      // Load config for this scene to local state
+      this.loadConfig()
+
+      // Load progress from store into local state
+      this.loadProgress()
 
-    // Load progress from store into local state
-    this.loadProgress()
+      this.launcherURI = this.getHostURI + '/launcher/'
 
-    this.launcherURI = this.getHostURI + '/launcher/'
+      let reference = null
 
-    let reference = null
+      // Load scene data from the API
+      await Promise.all([
+        this.getImage('max').then(res => (reference = res)),
+        this.getQualitiesList()
+      ])
 
-    // Load scene data from the API
-    await Promise.all([
-      this.getImage('max').then(res => (reference = res)),
-      this.getQualitiesList()
-    ])
+      this.referenceImage = reference.link
 
-    this.referenceImage = reference.link
+      this.maxWidth = reference.metadata.width
+      this.maxHeight = reference.metadata.height
 
-    this.maxWidth = reference.metadata.width
-    this.maxHeight = reference.metadata.height
+      // Load the cached configuration in the configurator component
+      if (this.lockConfig === false) this.$refs.configurator.setDefaultConfig(this.extractConfig)
 
-    // Load the cached configuration in the configurator component
-    if (this.lockConfig === false) this.$refs.configurator.setDefaultConfig(this.extractConfig)
+      // Load extracts if none were cached
+      // if (this.extracts.length === 0)
+      await this.setExtractConfig(this.extractConfig, this.$refs.configurator)
 
-    // Load extracts if none were cached
-    // if (this.extracts.length === 0)
-    await this.setExtractConfig(this.extractConfig, this.$refs.configurator)
+      this.saveProgress()
+      this.loadExperimentState()
 
-    this.saveProgress()
-    this.loadExperimentState()
+      // check window size
+      this.checkWindow()
+      window.addEventListener('resize', this.checkWindow)
 
-    // check window size
-    this.checkWindow()
-    window.addEventListener('resize', this.checkWindow)
+      // check if calibration is already done
+      if (this.sceneName === '50_shades_of_grey') {
+        // load current user progression
+        this.progression = this.getAllExperimentProgress()
+        let done = this.progression[this.experimentName][this.sceneName].done
+
+        console.log('Calibration scene is done', done)
+
+        if (done === true) {
+          console.log('Change of state for calibration')
+          this.calibrationCheck = true
+          this.runExpe = true
+          this.explanation = false
+          this.calibrationScene = true
+        }
+      }
+    }
   },
   methods: {
     startExperiment() {

+ 15 - 0
src/views/SelectExperimentScene.vue

@@ -146,11 +146,26 @@ export default {
         }
       }
     }
+
     // Randomize each group
     todo = shuffleArray(todo)
     working = shuffleArray(working)
     done = shuffleArray(done)
 
+    // here push in session (if not already there) current user advancement
+    if (window.sessionStorage.getItem('sin3d-nb-scenes') === null) {
+      window.sessionStorage.setItem('sin3d-nb-scenes', 0)
+    }
+
+    // check if necessary to show calibration before new scenes
+    if (window.sessionStorage.getItem('sin3d-nb-scenes') !== null) {
+      let nScenes = Number(window.sessionStorage.getItem('sin3d-nb-scenes'))
+
+      console.log('Redirect to calibration when selection')
+      if (nScenes % this.showCalibrationEvery === 0)
+        this.$router.push(`/experiments/${this.experimentName}/50_shades_of_grey`)
+    }
+
     // for the experiment user is redirect to current working on
     if (working.length > 0) {
       this.$router.push(working[0].experimentLink)