Skip to content

Commit

Permalink
Update 01 Version 1.0
Browse files Browse the repository at this point in the history
+ Decks
+ Questions
+ Options
+ Shuffle
+ Full keyboard navigation
  • Loading branch information
MustafaHi committed Mar 17, 2021
1 parent 88fbf60 commit 14bcf85
Show file tree
Hide file tree
Showing 16 changed files with 1,012 additions and 0 deletions.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Betakat

Study cards application, setup Decks fill it with Questions then challenge your self to Answer.

![Betakat Image](https://i.imgur.com/K6IHHOW.png)

> Version : 1.0
> [Guide](https://github.com/MustafaHi/Betakat/wiki/Guide)
> [Dev Guide](https://github.com/MustafaHi/Betakat/wiki/Dev-Guide)
> [Binary Release](https://github.com/MustafaHi/Betakat/releases)
> [Change Log & Features](https://github.com/MustafaHi/Betakat/wiki/Change-log-&-Features)
> More information in the [wiki](https://github.com/MustafaHi/Betakat/wiki)
**Features**

- Decks (sets of questions)
- Shuffle
- Full keyboard navigation
- Cross-platfrom (Windows, Macos, Linux)
- Lightweight `sizeof(app) < 10MB`

`>` [RoadMap](https://github.com/MustafaHi/Betakat/wiki/RoadMap)


[Download](https://github.com/MustafaHi/Betakat/releases)


## Credit
Built with [Sciter](https://github.com/c-smile/sciter-sdk), inspired by [GirkovArpa/slidercards](https://github.com/GirkovArpa/slidercards), using [Inter font](https://github.com/rsms/inter).
12 changes: 12 additions & 0 deletions logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions main.htm
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<html lang="en" window-frame="standard">
<head>
<meta charset="UTF-8">
<title>Betakat</title>
<link rel="stylesheet" href="style/icons.css">
<link rel="stylesheet" href="style/main.css">
<link rel="stylesheet" href="style/decks.css">
<link rel="stylesheet" href="style/questions.css">
<script type="text/tiscript" src="script/main.tis"></script>

<menu.context #deckMenu>
<li click=ENTER>Play</li>
<li click=Q>Questions</li>
<li click=E>Edit</li>
<li click=R>Delete</li>
</menu>
<menu.context #questionMenu>
<li click=E>Edit</li>
<li click=R>Delete</li>
</menu>
</head>
<body>

<nav>
<b #title>Betakat</b>
<!-- <button #bShuffle tabindex="-1"><b>S</b>huffle</button> -->
<button #bShowOptions tabindex="-1"><b>O</b>ptions</button>
</nav>

<content>

</content>

</body>
</html>
119 changes: 119 additions & 0 deletions script/data.tis
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
const dbPath = System.home("betaka.json");

function initFiles(forced = false) {
if (!System.scanFiles(dbPath) || forced) {
var file = Stream.openFile(dbPath, "wu");
var data = {
decks: [{
id: "MainDeck",
name: "Main Deck",
questions: [{
i: "Q12345",
q: "What is the name of this app?",
a: "Betakat",
t: []
}]
}],
options: {
letters: false,
random : false
}
};
// i : id, q : question, a : answer, d : deck, t : time, n : name
file.print(JSON.stringify(data," "));
file.close();
}
}
initFiles();


namespace DB {
var data;

function load() {
var file = Stream.openFile(dbPath, "ur");
data = parseData((file));
file.close();
if(!data) { initFiles(true); load(); }
}
function save() {
var file = Stream.openFile(dbPath, "wu");
file.print(JSON.stringify(data, " "));
file.close();
}

namespace decks {

function list() {
return data.decks;
}

function add(name) {
const deck = {
id: String.UID(),
name: name,
questions: []
};
data.decks.push(deck);

save();
}

function edit(D) {
var (i, deck) = data.decks.find(:d: d.id == D.id);
data.decks[i].name = D.name;

save();
}

function remove(id) {
var (i, deck) = data.decks.find(:d: d.id == id);
delete data.decks[i];

save();
}

}

namespace questions {

function list() {
var list = data.decks.find(:d: d.id == currentDeck).questions;
QuestionsList = data.options.random ? list.shuffle() : list;
return list;
}

function add(Q, A) {
const question = {
i: String.UID(),
q: Q,
a: A,
t: []
};

var (i, deck) = data.decks.find(:d: d.id == currentDeck);
data.decks[i].questions.push(question);

save();
}

function edit(Q) {
var (ind1, deck) = data.decks.find(:d: d.id == currentDeck);
var (ind2, question) = data.decks[ind1].questions.find(:q: q.i == Q.i);
data.decks[ind1].questions[ind2] = Q;

save();
}

function remove(id) {
var (ind1, deck) = data.decks.find(:d: d.id == currentDeck);
var (ind2, question) = data.decks[ind1].questions.find(:q: q.i == id);
delete data.decks[ind1].questions[ind2];

save();
}

}
}

DB.load();
55 changes: 55 additions & 0 deletions script/main.tis
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Betakat v1.0
// https://github.com/MustafaHi/Betakat

include "data.tis";
include "navigation.tis";

function Element.focus() { this.state.focus = true; }
function Element.current() {
if (var el = $(:current)) el.state.current = false;
this.state.current = true;
this.focus();
}

function Array.shuffle() {
var ri; const rnd = rand;
var shuffled = new Array(this.length);
for(var (i,v) in this) {
ri = rnd(i);
shuffled[i] = shuffled[ri];
shuffled[ri] = v;
}
return shuffled;
}


const Content = self[1][1]; // $(content);
var currentDeck;
var qIndex = 0;

var QuestionsList = [];


function self.ready() {
Nav.decks.list();

// center window on screen
initWindow();
}


function initWindow() {
const w = 440,
h = 650,
(sw, sh) = view.screenBox(#frame, #dimension);
view.move((sw / 2) - (w / 2), (sh / 2) - (h / 2), w, h, true);
view.windowResizable = false;
view.windowMaximizable = false;
}
function setDeck(deck) {
currentDeck = deck.id;
$(#title).text = "Betakat | " + deck[1].text;
}

event click $(a[href]) { Sciter.launch(this.@#href); return true; }
event click $(#bShowOptions) { Nav.options(); }
85 changes: 85 additions & 0 deletions script/navigation.tis
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
include "views/addDeck.tis";
include "views/decks.tis";

include "views/addQuestion.tis";
include "views/questions.tis";
include "views/ask.tis";


namespace Nav {

namespace decks {
// functions:
// - list // decks.tis
// - add|edit // addDeck.tis
}

namespace questions {
// functions:
// - list // questions.tis
// - add|edit // addQuestion.tis
// - ask // ask.tis
}

function options() {
Content.$content(
<div #form style="behavior: form;">
<button|checkbox(letters)>Normalize letters</button>
<button|checkbox(random)>Randomize questions</button>
</div>
<p style="margin-top: *; line-height: 1.5em">
<a href="https://github.com/MustafaHi/Betakat" style="color: white;">Betakat v1.0
<br/>
https://github.com/MustafaHi/Betakat
</a>
</p>
<footer>
<kbd>CTRL</kbd>
<kbd>+</kbd>
<kbd click=D><b>D</b>ecks</kbd>
</footer>
);
Content[0].value = DB.data.options;
Content[0][0].focus();

// Events:
eventsOff();
self << event ~keydown(e) {
if (e.shortcutKey) {
globalKeyBind(e);
}
switch (e.keyCode) {
case Event.VK_UP:
Content.$(:focus)?.prior.focus();
break;
case Event.VK_DOWN:
Content.$(:focus)?.next.focus();
break;
}
}
self.on("change", "#form", function() { DB.data.options = this.value; DB.save(); });
self.on("click", "[click]", function() {
self.sendKeyEvent({type: Event.KEY_DOWN, keyCode: eval("Event.VK_"+this.@#click), shortcutKey: true});
});
}

}


function globalKeyBind(e) {
switch (e.keyCode) {
case Event.VK_D:
Nav.decks.list();
break;
case Event.VK_O:
Nav.options();
break;
}
}

function eventsOff() {
self.off("~keydown");
self.off("dblclick");
self.off("change");
self.off("click");
}
Loading

0 comments on commit 14bcf85

Please sign in to comment.