mirror of
https://github.com/jorenchik/mdemory.git
synced 2026-03-22 00:26:21 +00:00
Frontend and communication
This commit is contained in:
@@ -2,40 +2,40 @@ package parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
"log"
|
|
||||||
"github.com/jorenchik/mdemory/src/compiler/lexer"
|
"github.com/jorenchik/mdemory/src/compiler/lexer"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Question interface {
|
type Question interface {
|
||||||
ToString() string;
|
ToString() string
|
||||||
}
|
}
|
||||||
|
|
||||||
type SingleAnswerQuestion struct {
|
type SingleAnswerQuestion struct {
|
||||||
id string;
|
ID string
|
||||||
question string;
|
Question string
|
||||||
answer string;
|
Answer string
|
||||||
section string;
|
Section string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Choice struct {
|
type Choice struct {
|
||||||
answer string;
|
answer string
|
||||||
isCorrect bool;
|
isCorrect bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type MultipleChoiceQuestion struct {
|
type MultipleChoiceQuestion struct {
|
||||||
id string;
|
id string
|
||||||
question string;
|
question string
|
||||||
choices []Choice;
|
choices []Choice
|
||||||
section string;
|
section string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (question SingleAnswerQuestion) ToString() string {
|
func (question SingleAnswerQuestion) ToString() string {
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
"<Single choice> (%s) %s: %s\n",
|
"<Single choice> (%s) %s: %s\n",
|
||||||
question.section,
|
question.Section,
|
||||||
strings.Trim(question.question, "\t\n "),
|
strings.Trim(question.Question, "\t\n "),
|
||||||
strings.Trim(question.answer, "\t\n "),
|
strings.Trim(question.Answer, "\t\n "),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ func (question MultipleChoiceQuestion)ToString() string {
|
|||||||
)
|
)
|
||||||
for _, el := range question.choices {
|
for _, el := range question.choices {
|
||||||
opener := '-'
|
opener := '-'
|
||||||
if (el.isCorrect) {
|
if el.isCorrect {
|
||||||
opener = '+'
|
opener = '+'
|
||||||
}
|
}
|
||||||
acc += fmt.Sprintf("\t%c %s\n", opener, strings.Trim(el.answer, "\t\n "))
|
acc += fmt.Sprintf("\t%c %s\n", opener, strings.Trim(el.answer, "\t\n "))
|
||||||
@@ -57,16 +57,16 @@ func (question MultipleChoiceQuestion)ToString() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type QuestionElement struct {
|
type QuestionElement struct {
|
||||||
isDash bool;
|
isDash bool
|
||||||
content string;
|
content string
|
||||||
}
|
}
|
||||||
|
|
||||||
var automata map[lexer.TokenType][]lexer.TokenType
|
var automata map[lexer.TokenType][]lexer.TokenType
|
||||||
|
|
||||||
type CompilerErr struct {
|
type CompilerErr struct {
|
||||||
message string;
|
message string
|
||||||
row int32;
|
row int32
|
||||||
column int32;
|
column int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e CompilerErr) Error() string {
|
func (e CompilerErr) Error() string {
|
||||||
@@ -132,7 +132,7 @@ func ValidateGrammar(tokens []lexer.Token) error {
|
|||||||
for i := 0; i < len(tokens)-1; i++ {
|
for i := 0; i < len(tokens)-1; i++ {
|
||||||
token := tokens[i]
|
token := tokens[i]
|
||||||
nextToken := tokens[i+1]
|
nextToken := tokens[i+1]
|
||||||
if (!contains(automata[token.TokenType], nextToken.TokenType)) {
|
if !contains(automata[token.TokenType], nextToken.TokenType) {
|
||||||
return CompilerErr{
|
return CompilerErr{
|
||||||
message: fmt.Sprintf(
|
message: fmt.Sprintf(
|
||||||
"Token %s cannot precede %s\n",
|
"Token %s cannot precede %s\n",
|
||||||
@@ -149,10 +149,10 @@ func ValidateGrammar(tokens []lexer.Token) error {
|
|||||||
|
|
||||||
func ParseQuestions(fileContents string) ([]Question, error) {
|
func ParseQuestions(fileContents string) ([]Question, error) {
|
||||||
tokens, err := lexer.TokenizeMdem([]rune(fileContents))
|
tokens, err := lexer.TokenizeMdem([]rune(fileContents))
|
||||||
if (err != nil) {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if (true) {
|
if true {
|
||||||
log.Println("Lexer output:")
|
log.Println("Lexer output:")
|
||||||
for _, el := range tokens {
|
for _, el := range tokens {
|
||||||
fmt.Print(el.ToString())
|
fmt.Print(el.ToString())
|
||||||
@@ -160,7 +160,7 @@ func ParseQuestions(fileContents string) ([]Question, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = ValidateGrammar(tokens)
|
err = ValidateGrammar(tokens)
|
||||||
if (err != nil) {
|
if err != nil {
|
||||||
log.Fatal(err.Error())
|
log.Fatal(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,23 +168,23 @@ func ParseQuestions(fileContents string) ([]Question, error) {
|
|||||||
section := ""
|
section := ""
|
||||||
i := 0
|
i := 0
|
||||||
for {
|
for {
|
||||||
if (i >= len(tokens)) {
|
if i >= len(tokens) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if (tokens[i].TokenType == lexer.ElementDashStart) {
|
if tokens[i].TokenType == lexer.ElementDashStart {
|
||||||
id := tokens[i+2].Content
|
id := tokens[i+2].Content
|
||||||
question := tokens[i+4].Content
|
question := tokens[i+4].Content
|
||||||
quesitonElements := []QuestionElement{}
|
quesitonElements := []QuestionElement{}
|
||||||
i += 6
|
i += 6
|
||||||
for {
|
for {
|
||||||
if (i + 1 >= len(tokens) ||
|
if i+1 >= len(tokens) ||
|
||||||
!(tokens[i].TokenType == lexer.ElementDashStart ||
|
!(tokens[i].TokenType == lexer.ElementDashStart ||
|
||||||
tokens[i].TokenType == lexer.ElementPlusStart) ||
|
tokens[i].TokenType == lexer.ElementPlusStart) ||
|
||||||
tokens[i+1].TokenType == lexer.IdentifierStart) {
|
tokens[i+1].TokenType == lexer.IdentifierStart {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
questionElement := QuestionElement{}
|
questionElement := QuestionElement{}
|
||||||
if (tokens[i].TokenType == lexer.ElementDashStart) {
|
if tokens[i].TokenType == lexer.ElementDashStart {
|
||||||
questionElement.isDash = true
|
questionElement.isDash = true
|
||||||
} else {
|
} else {
|
||||||
questionElement.isDash = false
|
questionElement.isDash = false
|
||||||
@@ -205,29 +205,29 @@ func ParseQuestions(fileContents string) ([]Question, error) {
|
|||||||
choice.isCorrect = !quesitonElements[k].isDash
|
choice.isCorrect = !quesitonElements[k].isDash
|
||||||
choices = append(choices, choice)
|
choices = append(choices, choice)
|
||||||
}
|
}
|
||||||
if (section != "") {
|
if section != "" {
|
||||||
question.section = section
|
question.section = section
|
||||||
}
|
}
|
||||||
question.choices = choices
|
question.choices = choices
|
||||||
questions = append(questions, question)
|
questions = append(questions, question)
|
||||||
} else if (len(quesitonElements) == 1) {
|
} else if len(quesitonElements) == 1 {
|
||||||
question := SingleAnswerQuestion{
|
question := SingleAnswerQuestion{
|
||||||
id: id,
|
ID: id,
|
||||||
question: question,
|
Question: question,
|
||||||
answer: quesitonElements[0].content,
|
Answer: quesitonElements[0].content,
|
||||||
}
|
}
|
||||||
if (section != "") {
|
if section != "" {
|
||||||
question.section = section
|
question.Section = section
|
||||||
}
|
}
|
||||||
questions = append(questions, question)
|
questions = append(questions, question)
|
||||||
}
|
}
|
||||||
} else if (tokens[i].TokenType == lexer.SectionIdentifierStart) {
|
} else if tokens[i].TokenType == lexer.SectionIdentifierStart {
|
||||||
section = tokens[i+1].Content
|
section = tokens[i+1].Content
|
||||||
i += 3;
|
i += 3
|
||||||
} else if (tokens[i].TokenType == lexer.SectionEnd) {
|
} else if tokens[i].TokenType == lexer.SectionEnd {
|
||||||
section = ""
|
section = ""
|
||||||
i += 1
|
i += 1
|
||||||
} else if (tokens[i].TokenType == lexer.EOF) {
|
} else if tokens[i].TokenType == lexer.EOF {
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
log.Fatalf(
|
log.Fatalf(
|
||||||
|
|||||||
16
src/mdemory-app/.vscode/launch.json
vendored
Normal file
16
src/mdemory-app/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Wails: build debug",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "exec",
|
||||||
|
"program": "${workspaceFolder}/myapp",
|
||||||
|
"preLaunchTask": "wails_debug_build",
|
||||||
|
"env": {},
|
||||||
|
"args": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
11
src/mdemory-app/.vscode/tasks.json
vendored
Normal file
11
src/mdemory-app/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "wails_debug_build",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "wails build -debug"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/jorenchik/mdemory/src/compiler/parser"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
)
|
)
|
||||||
@@ -29,24 +30,22 @@ func (a *App) Greet(name string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type File struct {
|
type File struct {
|
||||||
Name string;
|
Name string
|
||||||
IsDir bool;
|
IsDir bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Greet returns a greeting for the given name
|
func (a *App) GetRepoFiles(dirPath string) []File {
|
||||||
func (a *App) GetRepoFiles() []File {
|
|
||||||
dirPath := "/home/jorenchik/Code/mdemory/memorybase/"
|
|
||||||
dirEntries, err := os.ReadDir(dirPath)
|
dirEntries, err := os.ReadDir(dirPath)
|
||||||
if (err != nil) {
|
if err != nil {
|
||||||
return []File{}
|
return []File{}
|
||||||
}
|
}
|
||||||
files := []File{}
|
files := []File{}
|
||||||
exp, err := regexp.Compile(".+\\.mdem")
|
exp, err := regexp.Compile(".+\\.mdem")
|
||||||
for _, el := range dirEntries {
|
for _, el := range dirEntries {
|
||||||
if (err != nil) {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (el.IsDir() || exp.Match([]byte(el.Name()))) {
|
if el.IsDir() || exp.Match([]byte(el.Name())) {
|
||||||
file := File{}
|
file := File{}
|
||||||
file.Name = el.Name()
|
file.Name = el.Name()
|
||||||
file.IsDir = el.IsDir()
|
file.IsDir = el.IsDir()
|
||||||
@@ -55,3 +54,51 @@ func (a *App) GetRepoFiles() []File {
|
|||||||
}
|
}
|
||||||
return files
|
return files
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) ParseFile(filePath string) (string, error) {
|
||||||
|
fmt.Printf("Parse file requested. Path: %s\n", filePath)
|
||||||
|
dirName := "/home/jorenchik/Code/mdemory/memorybase/"
|
||||||
|
dir, err := os.ReadDir(dirName)
|
||||||
|
|
||||||
|
for _, el := range dir {
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
path := dirName + el.Name()
|
||||||
|
fmt.Println(path)
|
||||||
|
bytes, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Println(string(bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes, err := os.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("File opening error: %s\n", err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
fileContents := string(bytes)
|
||||||
|
questions, err := parser.ParseQuestions(fileContents)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Parsing error: %s\n", err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(questions); i++ {
|
||||||
|
question := questions[i]
|
||||||
|
switch q := question.(type) {
|
||||||
|
case parser.SingleAnswerQuestion:
|
||||||
|
fmt.Printf(
|
||||||
|
"Single Answer: question: %s; answer: %s",
|
||||||
|
q.Question,
|
||||||
|
q.Answer,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Returning file. Path: %s\n", filePath)
|
||||||
|
return fileContents, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,25 +1,42 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
|
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
|
||||||
<title>mdemory-app</title>
|
<title>mdemory-app</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="app">
|
<div class="master" id="app">
|
||||||
|
<div class="top-menu">
|
||||||
|
<div class="option">
|
||||||
|
<span>Base</span>
|
||||||
|
<div class="list">
|
||||||
|
<div>Save</div>
|
||||||
|
<div>Open</div>
|
||||||
|
<div>Reload</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="">
|
||||||
|
Help
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="main-layout">
|
<div class="main-layout">
|
||||||
<div>
|
|
||||||
<h3>memorybase</h3>
|
|
||||||
<div class="file-menus">
|
<div class="file-menus">
|
||||||
<h4 class="sidebar-heading">mdems</h4>
|
|
||||||
<div>
|
|
||||||
<div id="deck-list" class="deck-list">
|
|
||||||
<div class="mbase-actions">
|
<div class="mbase-actions">
|
||||||
|
<h3>memorybase</h3>
|
||||||
|
<div class="mbase-search">
|
||||||
<input class="repo-input" type="text" name="file" value="">
|
<input class="repo-input" type="text" name="file" value="">
|
||||||
<a id="reload-files" href="#">
|
<a id="reload-files" href="#">
|
||||||
Reload
|
Reload
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mbase-mdems">
|
||||||
|
<h4 class="sidebar-heading">mdems</h4>
|
||||||
|
<div id="deck-list" class="deck-list">
|
||||||
|
<!-- Mdem example -->
|
||||||
<!--<a class="deck-link" href="#">-->
|
<!--<a class="deck-link" href="#">-->
|
||||||
<!-- <div class="deck">-->
|
<!-- <div class="deck">-->
|
||||||
<!-- <span>></span>-->
|
<!-- <span>></span>-->
|
||||||
@@ -33,9 +50,10 @@
|
|||||||
<!--</a>-->
|
<!--</a>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="mbase-decks">
|
||||||
|
<!-- Deck example -->
|
||||||
<h4 class="sidebar-heading">decks</h4>
|
<h4 class="sidebar-heading">decks</h4>
|
||||||
<div class="deck-list">
|
<div>
|
||||||
<a class="deck-link" href="#">
|
<a class="deck-link" href="#">
|
||||||
<div class="deck">
|
<div class="deck">
|
||||||
cpp
|
cpp
|
||||||
@@ -54,22 +72,48 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>countries.mdem</h2>
|
||||||
|
<div class="deck-listing-box">
|
||||||
|
<div class="deck-listing-top">
|
||||||
|
<div>
|
||||||
|
<span>Flashcards: 12.</span>
|
||||||
|
<span>Page: 1 of 3.</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2>flashcards: countries</h2>
|
<button type="button">Train</button>
|
||||||
|
<button type="button">View stats</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="deck-listing">
|
<div class="deck-listing">
|
||||||
|
<div>
|
||||||
<div class="flashcard">
|
<div class="flashcard">
|
||||||
<span>></span>
|
<span>></span>
|
||||||
<span>What is the capital of Latvia?</span>
|
<span>What is the capital of Latvia?</span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
<div class="flashcard">
|
<div class="flashcard">
|
||||||
<span>></span>
|
<span>></span>
|
||||||
<span>What is the capital of Lithuania?</span>
|
<span>What is the capital of Lithuania?</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="flashcard">
|
||||||
|
<span>></span>
|
||||||
|
<span>What is the capital of Estonia?</span>
|
||||||
|
</div>
|
||||||
|
<div class="answer">
|
||||||
|
<span>-</span>
|
||||||
|
<span>Tallin</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="./src/main.ts" type="module"></script>
|
<script src="./src/main.ts" type="module"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,19 +1,16 @@
|
|||||||
.main-layout {
|
html {
|
||||||
display: grid;
|
background-color: rgba(27, 38, 54, 1);
|
||||||
grid-template-columns: .35fr 1fr; /* Creates 3 equal columns */
|
text-align: center;
|
||||||
height: 100%;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-layout > div:nth-child(1) {
|
body {
|
||||||
/*background: white;*/
|
box-sizing: content-box;
|
||||||
border-right: 1px solid gray;
|
margin: 0;
|
||||||
}
|
color: white;
|
||||||
|
font-family: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
|
||||||
.main-layout .deck-list {
|
"Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||||
padding: .5rem 1rem;
|
sans-serif;
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
/*gap: .5rem;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@@ -21,6 +18,43 @@ a {
|
|||||||
text-decoration: unset;
|
text-decoration: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
text-align: center;
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Nunito";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: local(""),
|
||||||
|
url("assets/fonts/nunito-v16-latin-regular.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-layout {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: .35fr 1fr;
|
||||||
|
flex-grow: 1;
|
||||||
|
/* height: 100%; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-layout > div:nth-child(1) {
|
||||||
|
border-right: 1px solid gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-layout .file-menus {
|
||||||
|
padding: 0 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.main-layout .deck {
|
.main-layout .deck {
|
||||||
border: 1px solid gray;
|
border: 1px solid gray;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
@@ -36,30 +70,55 @@ a {
|
|||||||
border-top: 1px solid gray;
|
border-top: 1px solid gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4 {
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.deck-listing {
|
.deck-listing {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 1rem;
|
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.deck-listing-top {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deck-listing-box {
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.deck-listing .flashcard {
|
.deck-listing .flashcard {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border: 1px solid white;
|
|
||||||
height: 80px;
|
height: 80px;
|
||||||
border-radius: .3rem;
|
border: 1px solid white;
|
||||||
|
border-top-left-radius: .3rem;
|
||||||
|
border-top-right-radius: .3rem;
|
||||||
|
border-bottom-left-radius: .3rem;
|
||||||
|
border-bottom-right-radius: .3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.deck-listing .flashcard > * {
|
.deck-listing .flashcard > * {
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.deck-listing .answer {
|
||||||
|
margin-top: -2px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 80px;
|
||||||
|
border: 1px solid white;
|
||||||
|
border-top: 0;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-left-radius: .3rem;
|
||||||
|
border-bottom-right-radius: .3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deck-listing .answer > * {
|
||||||
|
padding-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.repo-input {
|
.repo-input {
|
||||||
width: 99%;
|
width: 99%;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
@@ -68,11 +127,19 @@ h1, h2, h3, h4 {
|
|||||||
|
|
||||||
.mbase-actions {
|
.mbase-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: 0rem;
|
||||||
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: .5rem;
|
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mbase-search {
|
||||||
|
display: flex;
|
||||||
|
gap: .5rem;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.mbase-actions a {
|
.mbase-actions a {
|
||||||
font-size: .8rem;
|
font-size: .8rem;
|
||||||
display: block;
|
display: block;
|
||||||
@@ -82,11 +149,72 @@ h1, h2, h3, h4 {
|
|||||||
font-size: .9rem;
|
font-size: .9rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0 1rem;
|
padding: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.file-menus {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.file-menus > div {
|
.file-menus > div {
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mbase-actions {
|
||||||
|
height: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mbase-mdems {
|
||||||
|
max-height: 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mbase-decks {
|
||||||
|
max-height: 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu {
|
||||||
|
position: sticky;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
background: gray;
|
||||||
|
border: 1px solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu > div {
|
||||||
|
cursor: pointer;
|
||||||
|
border-right: 1px solid white;
|
||||||
|
padding: 1px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu .option {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu .option .list {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
background: gray;
|
||||||
|
width: 150px;
|
||||||
|
/* display: flex; */
|
||||||
|
display: none;
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: left;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
border: 1px solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu .option .list > div {
|
||||||
|
padding: 0 0 0 15px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu .option .list > div:nth-child(1) {
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu .option .list > div {
|
||||||
|
border-top: 1px solid white;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import './style.css';
|
import './style.css';
|
||||||
import './app.css';
|
import './app.css';
|
||||||
|
|
||||||
import {GetRepoFiles} from '../wailsjs/go/main/App';
|
import {GetRepoFiles, ParseFile} from '../wailsjs/go/main/App';
|
||||||
import {main} from '../wailsjs/go/models';
|
import {main} from '../wailsjs/go/models';
|
||||||
|
|
||||||
interface DeckFile {
|
interface DeckFile {
|
||||||
@@ -9,49 +9,56 @@ interface DeckFile {
|
|||||||
IsDir: boolean;
|
IsDir: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// console.log(await ParseFile("fjoewjf"));
|
||||||
|
|
||||||
function fetchFiles() {
|
function fetchFiles() {
|
||||||
GetRepoFiles().then((result: main.File[]) => {
|
GetRepoFiles("/home/jorenchik/Code/mdemory/memorybase/")
|
||||||
|
.then((result: main.File[]) => {
|
||||||
const files: DeckFile[] = result as DeckFile[]
|
const files: DeckFile[] = result as DeckFile[]
|
||||||
setDecklistFiles(files)
|
setDecklistFiles(files)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
fetchFiles()
|
fetchFiles()
|
||||||
|
|
||||||
|
let mbasePath = "/home/jorenchik/Code/mdemory/memorybase/"
|
||||||
|
|
||||||
|
async function fetchParsed(filename: string) {
|
||||||
|
console.log(filename);
|
||||||
|
try {
|
||||||
|
console.log(await ParseFile(mbasePath + filename));
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error:", error);
|
||||||
|
}
|
||||||
|
// let time = new Date().getTime();
|
||||||
|
// console.log(await ParseFile(mbasePath + filename));
|
||||||
|
// console.log(new Date().getTime() - time)
|
||||||
|
}
|
||||||
|
|
||||||
let decklist: Element | null = document.querySelector("#deck-list");
|
let decklist: Element | null = document.querySelector("#deck-list");
|
||||||
function setDecklistFiles(files: DeckFile[]) {
|
function setDecklistFiles(files: DeckFile[]) {
|
||||||
if (decklist) {
|
if (decklist) {
|
||||||
|
// removeAnchors
|
||||||
let deckFileAnchors = decklist.querySelectorAll(".deck-link")
|
let deckFileAnchors = decklist.querySelectorAll(".deck-link")
|
||||||
deckFileAnchors.forEach(i => {
|
deckFileAnchors.forEach(i => {
|
||||||
i.remove();
|
i.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// createAnchors
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
let element = document.createElement('a');
|
let element = document.createElement('a');
|
||||||
let angleHtml = ''
|
|
||||||
if (files[i].IsDir) {
|
|
||||||
angleHtml = "<span angle='true'>></span>"
|
|
||||||
}
|
|
||||||
element.setAttribute("href", "#")
|
|
||||||
element.setAttribute("class", "deck-link")
|
|
||||||
element.innerHTML = `
|
element.innerHTML = `
|
||||||
<div class="deck">
|
<div class="deck">
|
||||||
${ angleHtml }
|
|
||||||
${files[i].Name}
|
${files[i].Name}
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
element.setAttribute("href", "#")
|
||||||
|
element.setAttribute("class", "deck-link")
|
||||||
decklist.appendChild(element)
|
decklist.appendChild(element)
|
||||||
if (files[i].IsDir) {
|
|
||||||
let angle: HTMLElement | null = element.querySelector("[angle='true']")
|
element.addEventListener('click', _ => {
|
||||||
element.addEventListener("click", _clickable => {
|
fetchParsed(element.innerText);
|
||||||
let style: CSSStyleDeclaration | undefined = angle?.style
|
});
|
||||||
if (style) {
|
|
||||||
if (style["rotate"] == "90deg") {
|
|
||||||
style["rotate"] = "";
|
|
||||||
} else {
|
|
||||||
style["rotate"] = "90deg";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
html {
|
|
||||||
background-color: rgba(27, 38, 54, 1);
|
|
||||||
text-align: center;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
color: white;
|
|
||||||
font-family: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
|
|
||||||
"Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
|
||||||
sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Nunito";
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
src: local(""),
|
|
||||||
url("assets/fonts/nunito-v16-latin-regular.woff2") format("woff2");
|
|
||||||
}
|
|
||||||
|
|
||||||
#app {
|
|
||||||
height: 100vh;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
import {main} from '../models';
|
import {main} from '../models';
|
||||||
|
|
||||||
export function GetRepoFiles():Promise<Array<main.File>>;
|
export function GetRepoFiles(arg1:string):Promise<Array<main.File>>;
|
||||||
|
|
||||||
export function Greet(arg1:string):Promise<string>;
|
export function Greet(arg1:string):Promise<string>;
|
||||||
|
|
||||||
|
export function ParseFile(arg1:string):Promise<string>;
|
||||||
|
|||||||
@@ -2,10 +2,14 @@
|
|||||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
export function GetRepoFiles() {
|
export function GetRepoFiles(arg1) {
|
||||||
return window['go']['main']['App']['GetRepoFiles']();
|
return window['go']['main']['App']['GetRepoFiles'](arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Greet(arg1) {
|
export function Greet(arg1) {
|
||||||
return window['go']['main']['App']['Greet'](arg1);
|
return window['go']['main']['App']['Greet'](arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function ParseFile(arg1) {
|
||||||
|
return window['go']['main']['App']['ParseFile'](arg1);
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ module mdemory-app
|
|||||||
|
|
||||||
go 1.22.5
|
go 1.22.5
|
||||||
|
|
||||||
require github.com/wailsapp/wails/v2 v2.9.1
|
require (
|
||||||
|
github.com/jorenchik/mdemory/src/compiler v0.0.0-00010101000000-000000000000
|
||||||
|
github.com/wailsapp/wails/v2 v2.9.1
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/bep/debounce v1.2.1 // indirect
|
github.com/bep/debounce v1.2.1 // indirect
|
||||||
|
|||||||
Reference in New Issue
Block a user