Can ask student browser where they are in the page
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
nemunaire 2022-09-06 19:26:05 +02:00
parent 86cc2cad4a
commit ff5cefa7ac
3 changed files with 79 additions and 7 deletions

View File

@ -35,7 +35,7 @@ func declareAPIAdminDirectRoutes(router *gin.RouterGroup) {
} }
func WSSurveyStats(sid int64) map[string]interface{} { func WSSurveyStats(sid int64) map[string]interface{} {
var users []string var users []map[string]interface{}
var nb int var nb int
WSClientsMutex.RLock() WSClientsMutex.RLock()
@ -43,7 +43,10 @@ func WSSurveyStats(sid int64) map[string]interface{} {
if w, ok := WSClients[sid]; ok { if w, ok := WSClients[sid]; ok {
nb = len(w) nb = len(w)
for _, ws := range w { for _, ws := range w {
users = append(users, ws.u.Login) users = append(users, map[string]interface{}{
"id": ws.u.Id,
"login": ws.u.Login,
})
} }
} }
@ -139,6 +142,26 @@ func SurveyWS(c *gin.Context) {
ch <- msgCurrentState(survey) ch <- msgCurrentState(survey)
go SurveyWS_run(ws, ch, survey.Id, u) go SurveyWS_run(ws, ch, survey.Id, u)
go func(c chan WSMessage, sid int) {
var v WSMessage
var err error
for {
err = wsjson.Read(context.Background(), ws, &v)
if err != nil {
log.Println("Error when receiving message:", err)
close(c)
break
}
if v.Action == "myscroll" {
v.UserId = &u.Id
v.SurveyId = &survey.Id
WSAdminWriteAll(v)
} else {
log.Println("Unknown ws response:", v.Action)
}
}
}(ch, int(survey.Id))
} }
func WSWriteAll(message WSMessage) { func WSWriteAll(message WSMessage) {
@ -423,6 +446,8 @@ func SurveyWSAdmin(c *gin.Context) {
} }
} }
} }
} else if v.Action == "where_are_you" {
survey.WSWriteAll(v)
} else { } else {
log.Println("Unknown admin action:", v.Action) log.Println("Unknown admin action:", v.Action)
} }

View File

@ -89,6 +89,16 @@
} }
updateUsers(); updateUsers();
let scroll_states = { };
let scroll_mean = 0;
$: {
let mean = 0;
for (const k in scroll_states) {
mean += scroll_states[k];
}
scroll_mean = mean / Object.keys(scroll_states).length;
}
let responsesbyid = { }; let responsesbyid = { };
$: { $: {
const tmp = { }; const tmp = { };
@ -200,6 +210,13 @@
} else if (data.action && data.action == "new_ask") { } else if (data.action && data.action == "new_ask") {
asks.push({"id": data.question, "content": data.value, "userid": data.user}); asks.push({"id": data.question, "content": data.value, "userid": data.user});
asks = asks; asks = asks;
} else if (data.action && data.action == "myscroll" && wsstats && wsstats.users) {
scroll_states[data.user] = parseFloat(data.value);
for (const k in wsstats.users) {
if (wsstats.users[k].id == data.user) {
wsstats.users[k].myscroll = scroll_states[data.user];
}
}
} else if (data.action && data.action == "end") { } else if (data.action && data.action == "end") {
ws.close(); ws.close();
updateSurvey(); updateSurvey();
@ -646,23 +663,50 @@
<i class="bi bi-arrow-clockwise"></i> <i class="bi bi-arrow-clockwise"></i>
<i class="bi bi-people"></i> <i class="bi bi-people"></i>
</button> </button>
<h3> <button
type="button"
class="btn btn-sm btn-warning ms-1 float-end"
on:click={() => { scroll_states = {}; ws.send('{"action":"where_are_you"}')} }
title="Rapporter l'avancement"
>
<i class="bi bi-geo-fill"></i>
</button>
<h3 id="users">
Connectés Connectés
{#if wsstats} {#if wsstats}
<small class="text-muted">{wsstats.nb_clients} utilisateurs</small> <small class="text-muted">{wsstats.nb_clients} utilisateurs</small>
{/if} {/if}
{#if scroll_mean}
<small
class:text-danger={scroll_mean >= 0 && scroll_mean < 0.2}
class:text-warning={scroll_mean >= 0.2 && scroll_mean < 0.6}
class:text-info={scroll_mean >= 0.6 && scroll_mean < 0.9}
class:text-success={scroll_mean >= 0.9}
>Avancement global&nbsp;: {Math.trunc(scroll_mean*10000)/100} %</small>
{/if}
</h3> </h3>
{#if wsstats && wsstats.users} {#if wsstats && wsstats.users}
<div class="row row-cols-5 py-3"> <div class="row row-cols-5 py-3">
{#each wsstats.users as login, lid (lid)} {#each wsstats.users as user, lid (lid)}
<div class="col"> <div class="col">
<div class="card"> <div class="card">
<img alt="{login}" src="//photos.cri.epita.fr/thumb/{login}" class="card-img-top"> <img alt="{user.login}" src="//photos.cri.epita.fr/thumb/{user.login}" class="card-img-top">
<div class="card-footer text-center text-truncate p-0"> <div class="card-footer text-center text-truncate p-0">
<a href="users/{login}" target="_blank"> <a href="users/{user.login}" target="_blank">
{login} {user.login}
</a> </a>
</div> </div>
{#if user.myscroll != null}
<div
class="card-footer py-0 px-1"
class:bg-danger={user.myscroll >= 0 && user.myscroll < 0.2}
class:bg-warning={user.myscroll >= 0.2 && user.myscroll < 0.6}
class:bg-info={user.myscroll >= 0.6 && user.myscroll < 0.9}
class:bg-success={user.myscroll >= 0.9}
>
Avancement&nbsp;: {Math.trunc(user.myscroll*10000)/100}&nbsp;%
</div>
{/if}
</div> </div>
</div> </div>
{/each} {/each}

View File

@ -118,6 +118,9 @@
} else { } else {
timer_init = null; timer_init = null;
} }
} else if (data.action && data.action == "where_are_you") {
ws.send('{"action":"myscroll", "value": "' + (window.scrollY/window.scrollMaxY) +'", "question": '+show_question+', "corrected": '+(survey.corrected==true)+'}')
} else { } else {
show_question = null; show_question = null;
if (timer_cancel) { if (timer_cancel) {