diff --git a/.gitignore b/.gitignore index 129d522..7f8fa19 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ build/bin node_modules frontend/dist +data + diff --git a/app.go b/app.go index 35e3681..ab4c175 100644 --- a/app.go +++ b/app.go @@ -3,14 +3,19 @@ package main import ( "context" + "git.andreafazzi.eu/andrea/probo/client" "git.andreafazzi.eu/andrea/probo/models" "git.andreafazzi.eu/andrea/probo/store/file" + "github.com/fsnotify/fsnotify" + "github.com/wailsapp/wails/v2/pkg/runtime" ) // App struct type App struct { - ctx context.Context - store *file.FileProboCollectorStore + ctx context.Context + + store *file.FileProboCollectorStore + watcher *fsnotify.Watcher } type Quiz struct { @@ -34,6 +39,68 @@ func (a *App) startup(ctx context.Context) { a.ctx = ctx } +func (a *App) onShutdown(ctx context.Context) { + a.watcher.Close() +} + +func (a *App) onDomReady(ctx context.Context) { + var err error + + // Create new watcher. + a.watcher, err = fsnotify.NewWatcher() + if err != nil { + runtime.LogFatal(ctx, err.Error()) + } + + // Start listening for events. + go func() { + runtime.LogDebug(ctx, "Filesystem watcher initialized...") + for { + select { + case event, ok := <-a.watcher.Events: + if !ok { + return + } + runtime.LogDebugf(ctx, "Event: %v", event) + if event.Has(fsnotify.Write) { + runtime.LogDebugf(ctx, "Modified file: %v", event.Name) + runtime.EventsEmit(ctx, "fsChangeEvent") + } + case err, ok := <-a.watcher.Errors: + if !ok { + return + } + runtime.LogDebugf(ctx, "Error: %v", err) + } + } + }() + + // Add a path. + + runtime.LogDebugf(ctx, "Begin watching path %v", a.store.Dir) + + err = a.watcher.Add(a.store.Dir) + if err != nil { + runtime.LogFatalf(ctx, "Error: %v", err) + } +} + func (a *App) ReadAllQuizzes() ([]*models.Quiz, error) { return a.store.ReadAllQuizzes() } + +func (a *App) MarkdownFromQuiz(quiz *models.Quiz) (string, error) { + return file.MarkdownFromQuiz(quiz) +} + +func (a *App) QuizFromMarkdown(markdown string) (*client.Quiz, error) { + return file.QuizFromMarkdown(markdown) +} + +func (a *App) UpdateQuiz(quiz *client.Quiz, id string) (*models.Quiz, error) { + return a.store.UpdateQuiz(&client.CreateUpdateQuizRequest{Quiz: quiz}, id) +} + +func (a *App) CreateQuiz(quiz *client.Quiz) (*models.Quiz, error) { + return a.store.CreateQuiz(&client.CreateUpdateQuizRequest{Quiz: quiz}) +} diff --git a/data/quizzes/question_1_1.md b/data/quizzes/question_1_1.md deleted file mode 100644 index c310330..0000000 --- a/data/quizzes/question_1_1.md +++ /dev/null @@ -1,6 +0,0 @@ -Per intensità di corrente elettrica si intende - -* La quantità di carica che scorre in un circuito per unità di tempo -* La differenza di potenziale elettrico -* La quantità di carica elettrica -* L'accelerazione a cui sono sottoposti gli elettroni all'interno del circuito diff --git a/data/quizzes/question_1_11.md b/data/quizzes/question_1_11.md deleted file mode 100644 index 020b89d..0000000 --- a/data/quizzes/question_1_11.md +++ /dev/null @@ -1,6 +0,0 @@ -L'amperometro è - -* Uno strumento di misura della corrente elettrica -* Uno strumento di misura della differenza di potenziale -* Si collega al circuito in parallelo -* Uno strumento di misura della carica elettrostatica diff --git a/data/quizzes/question_1_12.md b/data/quizzes/question_1_12.md deleted file mode 100644 index 4b95c71..0000000 --- a/data/quizzes/question_1_12.md +++ /dev/null @@ -1,6 +0,0 @@ -Il voltmetro - -* Serve a misurare la differenza di potenziale tra due punti del circuito -* Serve a misurare la corrente elettrica circolante tra due punti del circuito -* Misura la carica elettrostatica presente sulle armature di un condensatore -* E' sempre collegato in serie diff --git a/data/quizzes/question_1_2.md b/data/quizzes/question_1_2.md deleted file mode 100644 index 1ae9707..0000000 --- a/data/quizzes/question_1_2.md +++ /dev/null @@ -1,6 +0,0 @@ -La corrente elettrica si misura in - -* Ampere (A) -* Volt (V) -* Coulomb (C) -* Metri al secondo (m/s) diff --git a/data/quizzes/question_1_3.md b/data/quizzes/question_1_3.md deleted file mode 100644 index a8489b3..0000000 --- a/data/quizzes/question_1_3.md +++ /dev/null @@ -1,6 +0,0 @@ -Un generatore all'interno di un circuito elettrico ha la funzione di - -* Mantenere le cariche in movimento mantenendo stabile una differenza di potenziale -* Generare energia dal nulla -* Rallentare le cariche che altrimenti si muoverebbero troppo velocemente -* Nessuna delle risposte previste è corretta diff --git a/data/quizzes/question_1_4.md b/data/quizzes/question_1_4.md deleted file mode 100644 index eb6933a..0000000 --- a/data/quizzes/question_1_4.md +++ /dev/null @@ -1,6 +0,0 @@ -La prima legge di Ohm descrive la relazione tra - -* Corrente elettrica e differenza di potenziale -* Tra potenza dissipata e corrente elettrica -* Tra capacità di un condensatore e differenza di potenziale -* Tra potenziale gravitazionale e corrente elettrica diff --git a/data/quizzes/question_1_5.md b/data/quizzes/question_1_5.md deleted file mode 100644 index a3ec0b1..0000000 --- a/data/quizzes/question_1_5.md +++ /dev/null @@ -1,6 +0,0 @@ -La resistenza elettrica R - -* E' pari al rapporto tra differenza di potenziale e corrente elettrica e si misura in ohm -* E' pari al rapporto tra differenza di potenziale e forza elettromotrice e si misura in volt -* E' pari al prodotto tra differenza di potenziale e corrente elettrica e si misura in ohm -* E' pari al rapporto tra differenza di potenziale e potenza dissipata e si misura in joule diff --git a/data/quizzes/question_1_6.md b/data/quizzes/question_1_6.md deleted file mode 100644 index fb57d18..0000000 --- a/data/quizzes/question_1_6.md +++ /dev/null @@ -1,6 +0,0 @@ -Il cosidetto effetto Joule - -* Descrive la potenza dissipata in un circuito sotto forma di calore -* Descrive la quantità di calore dissipata dal circuito -* Descrive la differenza di potenziale presente nel circuito -* Nessuna delle risposte previste è corretta diff --git a/data/quizzes/question_1_7.md b/data/quizzes/question_1_7.md deleted file mode 100644 index f4bb6fb..0000000 --- a/data/quizzes/question_1_7.md +++ /dev/null @@ -1,6 +0,0 @@ -La seconda legge di Ohm - -* Mette in relazione la resistenza di un conduttore con la sua lunghezza e la sua sezione -* Mette in relazione la differenza di potenziale con la corrente elettrica -* Non esiste -* Descrive la quantità di calore dissipata da un circuito per effetto Joule diff --git a/data/quizzes/question_1_8.md b/data/quizzes/question_1_8.md deleted file mode 100644 index 7dea458..0000000 --- a/data/quizzes/question_1_8.md +++ /dev/null @@ -1,6 +0,0 @@ -Affinché in un circuito possa circolare corrente continua, il generatore di tensione - -* Fornisce una potenza pari a quella dissipata per effetto Joule -* Fornisce una potenza minore a quella dissipata per effetto Joule -* Rallenta le cariche elettriche -* Dev'essere spento diff --git a/data/quizzes/question_1_9.md b/data/quizzes/question_1_9.md deleted file mode 100644 index 1158ad9..0000000 --- a/data/quizzes/question_1_9.md +++ /dev/null @@ -1,6 +0,0 @@ -Se in un circuito l'energia non venisse dissipata per effetto Joule - -* Una volta attivata la circolazione della corrente elettrica, le cariche continuerebbero a muoversi indefinitamente -* Le cariche continuerebbero a muoversi indefinitamente senza necessità di attivare la loro circolazione -* Allora sarebbe dissipata sotto forma di calore -* Le cariche si fermerebbero immediatamente diff --git a/data/quizzes/test.md b/data/quizzes/test.md deleted file mode 100644 index d04f734..0000000 --- a/data/quizzes/test.md +++ /dev/null @@ -1,7 +0,0 @@ -Quali grandezze fisiche mette in relazione l'esperienza di Oersted? - -* Campo magnetico con campo elettrico -* Campo gravitazionale con campo elettrico -* L'energia nucleare forte con quella debole -* Cariche elettriche con densità di carica superficiale - diff --git a/data/quizzes/test_2.md b/data/quizzes/test_2.md deleted file mode 100644 index c072694..0000000 --- a/data/quizzes/test_2.md +++ /dev/null @@ -1,6 +0,0 @@ -La corrente elettrica rappresenta - -* Un moto ordinato di cariche elettriche -* Un moto disordinato di cariche elettriche -* Un moto disordinato di masse -* Un moto ordinato di masse diff --git a/frontend/src/lib/components/QuizCard.svelte b/frontend/src/lib/components/QuizCard.svelte index de13ee2..4064420 100644 --- a/frontend/src/lib/components/QuizCard.svelte +++ b/frontend/src/lib/components/QuizCard.svelte @@ -1,49 +1,95 @@ -
-
-
-
- - +
+ {#if editing} + + {:else} +
+
+
+ + +
+

{quiz.hash.slice(0,10)+'…'}

-

{quiz.hash.slice(0,10)+'…'}

-
-
-
-

- {quiz.question.Text} -

-
-
- {#each quiz.answers as answer} + +
+

+ {quiz.question.text} +

+ +
- {/each} -
- -
-
-
- #corrente - #quinte - #circuiti -
-
- Created on {new Date().toLocaleDateString()} -
-
+ {#each quiz.answers as answer} + {#if answer.id != quiz.correct.id} + + {/if} + {/each} +
+ +
+ + {/if}
diff --git a/frontend/src/lib/wailsjs/go/main/App.d.ts b/frontend/src/lib/wailsjs/go/main/App.d.ts index 3818c17..840d21f 100755 --- a/frontend/src/lib/wailsjs/go/main/App.d.ts +++ b/frontend/src/lib/wailsjs/go/main/App.d.ts @@ -1,5 +1,14 @@ // Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL // This file is automatically generated. DO NOT EDIT +import {client} from '../models'; import {models} from '../models'; +export function CreateQuiz(arg1:client.Quiz):Promise; + +export function MarkdownFromQuiz(arg1:models.Quiz):Promise; + +export function QuizFromMarkdown(arg1:string):Promise; + export function ReadAllQuizzes():Promise>; + +export function UpdateQuiz(arg1:client.Quiz,arg2:string):Promise; diff --git a/frontend/src/lib/wailsjs/go/main/App.js b/frontend/src/lib/wailsjs/go/main/App.js index ce99eee..3cfd599 100755 --- a/frontend/src/lib/wailsjs/go/main/App.js +++ b/frontend/src/lib/wailsjs/go/main/App.js @@ -2,6 +2,22 @@ // Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL // This file is automatically generated. DO NOT EDIT +export function CreateQuiz(arg1) { + return window['go']['main']['App']['CreateQuiz'](arg1); +} + +export function MarkdownFromQuiz(arg1) { + return window['go']['main']['App']['MarkdownFromQuiz'](arg1); +} + +export function QuizFromMarkdown(arg1) { + return window['go']['main']['App']['QuizFromMarkdown'](arg1); +} + export function ReadAllQuizzes() { return window['go']['main']['App']['ReadAllQuizzes'](); } + +export function UpdateQuiz(arg1, arg2) { + return window['go']['main']['App']['UpdateQuiz'](arg1, arg2); +} diff --git a/frontend/src/lib/wailsjs/go/models.ts b/frontend/src/lib/wailsjs/go/models.ts index f3a2330..8c8e7d4 100755 --- a/frontend/src/lib/wailsjs/go/models.ts +++ b/frontend/src/lib/wailsjs/go/models.ts @@ -1,13 +1,104 @@ +export namespace client { + + export class Question { + text: string; + + static createFrom(source: any = {}) { + return new Question(source); + } + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.text = source["text"]; + } + } + export class Answer { + text: string; + correct: boolean; + + static createFrom(source: any = {}) { + return new Answer(source); + } + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.text = source["text"]; + this.correct = source["correct"]; + } + } + export class Quiz { + question?: Question; + answers: Answer[]; + + static createFrom(source: any = {}) { + return new Quiz(source); + } + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.question = this.convertValues(source["question"], Question); + this.answers = this.convertValues(source["answers"], Answer); + } + + convertValues(a: any, classs: any, asMap: boolean = false): any { + if (!a) { + return a; + } + if (a.slice) { + return (a as any[]).map(elem => this.convertValues(elem, classs)); + } else if ("object" === typeof a) { + if (asMap) { + for (const key of Object.keys(a)) { + a[key] = new classs(a[key]); + } + return a; + } + return new classs(a); + } + return a; + } + } + +} + export namespace models { + export class Answer { + id: string; + text: string; + + static createFrom(source: any = {}) { + return new Answer(source); + } + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.id = source["id"]; + this.text = source["text"]; + } + } + export class Question { + id: string; + text: string; + answer_ids: string[]; + + static createFrom(source: any = {}) { + return new Question(source); + } + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.id = source["id"]; + this.text = source["text"]; + this.answer_ids = source["answer_ids"]; + } + } export class Quiz { id: string; hash: string; - // Go type: Question - question?: any; + question?: Question; answers: Answer[]; - // Go type: Answer - correct?: any; + correct?: Answer; type: number; static createFrom(source: any = {}) { @@ -18,9 +109,9 @@ export namespace models { if ('string' === typeof source) source = JSON.parse(source); this.id = source["id"]; this.hash = source["hash"]; - this.question = this.convertValues(source["question"], null); + this.question = this.convertValues(source["question"], Question); this.answers = this.convertValues(source["answers"], Answer); - this.correct = this.convertValues(source["correct"], null); + this.correct = this.convertValues(source["correct"], Answer); this.type = source["type"]; } diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index 5a891bf..178ebe8 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -1,18 +1,70 @@ -
- - + {#if creatingNewQuiz} +
+ +
+ {:else} + + {/if} {#each data.quizzes as quiz} {/each} diff --git a/frontend/svelte.config.js b/frontend/svelte.config.js index 4a5affc..9ec97ca 100644 --- a/frontend/svelte.config.js +++ b/frontend/svelte.config.js @@ -16,7 +16,8 @@ const config = { // See https://kit.svelte.dev/docs/adapters for more information about adapters. adapter: adapter({ fallback: 'index.html' - }) + }), + files: { lib: './src/lib/' } } }; export default config; diff --git a/go.mod b/go.mod index fc191a0..495d2a2 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,8 @@ module changeme go 1.18 require ( - git.andreafazzi.eu/andrea/probo v0.0.0-20230707161509-7a1135de0fd3 + git.andreafazzi.eu/andrea/probo v0.0.0-20230713044636-dd4636a89dd0 + github.com/fsnotify/fsnotify v1.6.0 github.com/wailsapp/wails/v2 v2.5.1 ) @@ -29,7 +30,7 @@ require ( github.com/valyala/fasttemplate v1.2.2 // indirect github.com/wailsapp/mimetype v1.4.1 // indirect golang.org/x/crypto v0.11.0 // indirect - golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect + golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb // indirect golang.org/x/net v0.12.0 // indirect golang.org/x/sys v0.10.0 // indirect golang.org/x/text v0.11.0 // indirect diff --git a/go.sum b/go.sum index 471b850..807fe08 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,12 @@ -git.andreafazzi.eu/andrea/probo v0.0.0-20230707161509-7a1135de0fd3 h1:Ldb0JVvfbvWLyaJfPefWIy85I1c2GO1dPOSVg/vcVMw= -git.andreafazzi.eu/andrea/probo v0.0.0-20230707161509-7a1135de0fd3/go.mod h1:lv4LRymK1SeOIs3Y1nJDA/8Ps/fRHQJDbIR+4Tdxtm4= +git.andreafazzi.eu/andrea/probo v0.0.0-20230713044636-dd4636a89dd0 h1:WrR000VnRjLXbdRDz61NBzoUpJGdGTD2TRgubCxEoks= +git.andreafazzi.eu/andrea/probo v0.0.0-20230713044636-dd4636a89dd0/go.mod h1:lv4LRymK1SeOIs3Y1nJDA/8Ps/fRHQJDbIR+4Tdxtm4= github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= @@ -65,8 +67,8 @@ github.com/wailsapp/wails/v2 v2.5.1 h1:mfG+2kWqQXYOwdgI43HEILjOZDXbk5woPYI3jP2b+ github.com/wailsapp/wails/v2 v2.5.1/go.mod h1:jbOZbcr/zm79PxXxAjP8UoVlDd9wLW3uDs+isIthDfs= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= -golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb h1:xIApU0ow1zwMa2uL1VDNeQlNVFTWMQxZUZCMDy0Q4Us= +golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= @@ -79,6 +81,7 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/main.go b/main.go index 578d2bb..386d846 100644 --- a/main.go +++ b/main.go @@ -28,6 +28,8 @@ func main() { }, BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1}, OnStartup: app.startup, + OnDomReady: app.onDomReady, + OnShutdown: app.onShutdown, Bind: []interface{}{ app, },