Problem: we don't have SR
continuous-integration/drone/push Build was killed Details

Solution: add SR
master
Peter Stuifzand 2 years ago
parent 569bef3226
commit b33cfeb395

@ -369,7 +369,7 @@ function Editor(holder, input) {
transformTable.call(this, editor, id, element); transformTable.call(this, editor, id, element);
return return
} else if (converted.startsWith("```", 0) || converted.startsWith("$$", 0)) { } else if (converted.startsWith("```", 0) || converted.startsWith("$$", 0)) {
converted = MD.render(converted) converted = MD.renderInline(converted)
} else if (converted.startsWith("=", 0)) { } else if (converted.startsWith("=", 0)) {
transformMathExpression(converted, scope) transformMathExpression(converted, scope)
.then(converted => { .then(converted => {

@ -5,18 +5,24 @@ import qs from "querystring";
function fillResult($modal, result) { function fillResult($modal, result) {
$modal.data('block-id', result.id) $modal.data('block-id', result.id)
$modal.data('block-original-text', result.line) $modal.data('block-original-text', result.line)
let visibleText = result.line.replace(/\s*#\S+/g, '').trim();
$modal.data('block-text-without-tags', visibleText)
$modal.find('.block-title').show().text(result.title) $modal.find('.block-title').show().text(result.title)
$modal.find('.block-text').show().val(result.line) $modal.find('.block-text').show().val(visibleText)
} }
function replaceBlock(id, oldText) { async function replaceBlock(id, oldText) {
return fetch('/api/block/replace', { if (oldText === false) return false;
await fetch('/api/block/replace', {
method: 'post', method: 'post',
headers: { headers: {
'Content-Type': 'application/x-www-form-urlencoded', 'Content-Type': 'application/x-www-form-urlencoded',
}, },
body: qs.encode({id, text: oldText}), body: qs.encode({id, text: oldText}),
}); });
return true
} }
function appendBlock(id, newText) { function appendBlock(id, newText) {
@ -30,13 +36,12 @@ function appendBlock(id, newText) {
} }
function resetSRBox(text) { function resetSRBox(text) {
let newText = text.replace(/#(?:\[\[)?sr\/(\d+)(?:\]\])?/, '#sr/1'); return text + " #review #sr/1"
return newText;
} }
function processSRBox(review, originalText) { function processSRBox(review, originalText) {
let oldText = originalText let oldText = originalText
.replace(/#(?:\[\[)?sr\/(\d+)(?:\]\])?/, function (text, srCount) { .replace(/#sr\/(\d+)/, function (text, srCount) {
if (review === 'never') return ''; if (review === 'never') return '';
let nextCount = 1; let nextCount = 1;
const count = parseInt(srCount) const count = parseInt(srCount)
@ -45,15 +50,22 @@ function processSRBox(review, originalText) {
if (review === 'later') nextCount = count + 1 if (review === 'later') nextCount = count + 1
return '#sr/' + nextCount; return '#sr/' + nextCount;
}).trim() }).trim()
if (review === 'never') return oldText.replace(/#(?:\[\[)?review(?:\]\])?/, '') if (review === 'never') return oldText.replace(/#review/, '')
if (oldText === originalText) return false
return oldText return oldText
} }
$(function () { $(function () {
let reviewBlocks = []; let reviewBlocks = [];
let isSR = false;
$('.start-review, .start-sr').on('click', function () {
isSR = $(this).hasClass('start-sr')
$('.start-review').on('click', function () { // Use different queries for different days
search.startQuery('+tag:review +tag:sr/1', {internal: false}).then((results) => { const query = isSR ? '+tag:sr tag:"sr/1" tag:"sr/2"' : '+tag:review tag:"sr/1"'
search.startQuery(query, {internal: false}).then((results) => {
reviewBlocks = results reviewBlocks = results
$('.review-modal .end-of-review').hide(); $('.review-modal .end-of-review').hide();
@ -81,16 +93,21 @@ $(function () {
window.location.reload() window.location.reload()
}); });
$('.modal .show-answer').on('click', function () {
$('.review-modal .block-answer').show();
});
$('.modal .review').on('click', function () { $('.modal .review').on('click', function () {
const $modal = $(this).parents('.modal') const $modal = $(this).parents('.modal')
const review = $(this).data('review') const review = $(this).data('review')
// NOTE: should we keep the review and sr/* tag in the editable text? // NOTE: should we keep the review and sr/* tag in the editable text?
const originalText = $modal.data('block-original-text') const originalText = $modal.data('block-original-text')
const originalTextWithoutTags = $modal.data('block-text-without-tags')
let text = $modal.find('.block-text').val() let text = $modal.find('.block-text').val()
let id = $modal.data('block-id') let id = $modal.data('block-id')
processText(review, text, originalText, id) processText(review, text, originalTextWithoutTags, originalText, id)
.then(() => { .then(() => {
if (reviewBlocks.length > 0) { if (reviewBlocks.length > 0) {
const first = reviewBlocks.shift() const first = reviewBlocks.shift()
@ -109,8 +126,8 @@ $(function () {
}).catch(e => console.log(e)) }).catch(e => console.log(e))
}); });
async function processText(review, text, originalText, id) { async function processText(review, text, originalTextWithoutTags, originalText, id) {
if (text !== originalText) { if (text !== originalTextWithoutTags) {
await appendBlock(id, resetSRBox(text)) await appendBlock(id, resetSRBox(text))
} }
await replaceBlock(id, processSRBox(review, originalText)) await replaceBlock(id, processSRBox(review, originalText))

@ -64,6 +64,10 @@ Plugin.prototype.parse = function (state, silent) {
Plugin.prototype.render = function (tokens, id, options, env) { Plugin.prototype.render = function (tokens, id, options, env) {
let {match: link, tag} = tokens[id].meta let {match: link, tag} = tokens[id].meta
if (tag) { if (tag) {
if (tag === 'metadata') {
let {key, value} = tokens[id].meta
return '<span class="metadata-key">'+key+'</span>: '+value;
}
if (link === 'TODO') { if (link === 'TODO') {
return '<input type="checkbox" class="checkbox">'; return '<input type="checkbox" class="checkbox">';
} else if (link === 'DONE') { } else if (link === 'DONE') {

@ -586,7 +586,7 @@ func saveLinksIncremental(dirname, title string) error {
titles[title] = true titles[title] = true
results = nil results = nil
for t, _ := range titles { for t := range titles {
results = append(results, Document{t}) results = append(results, Document{t})
} }

@ -1130,16 +1130,24 @@ func main() {
http.Error(w, "missing id", 400) http.Error(w, "missing id", 400)
return return
} }
repo := blockRepo{ repo := blockRepo{dirname: "data"}
dirname: "data",
}
block, err := repo.Load(id) block, err := repo.Load(id)
block.Text = r.Form.Get("text") block.Text = r.Form.Get("text")
err = repo.Save(id, block) err = repo.Save(id, block)
// update search index
searchObjects, err := createSearchObjects(id) searchObjects, err := createSearchObjects(id)
batch := searchIndex.NewBatch()
for _, so := range searchObjects { for _, so := range searchObjects {
searchIndex.Index(so.ID, so) err = batch.Index(so.ID, so)
if err != nil {
log.Println(err)
}
}
err = searchIndex.Batch(batch)
if err != nil {
log.Println(err)
} }
// TODO: update backlinks
return return
})) }))
http.HandleFunc("/api/block/append", wrapAuth(func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/api/block/append", wrapAuth(func(w http.ResponseWriter, r *http.Request) {
@ -1168,6 +1176,7 @@ func main() {
block.Children = append(block.Children, generatedID) block.Children = append(block.Children, generatedID)
err = repo.Save(id, block) err = repo.Save(id, block)
// update search index
searchObjects, err := createSearchObjects(id) searchObjects, err := createSearchObjects(id)
spew.Dump("searchObjects", searchObjects) spew.Dump("searchObjects", searchObjects)

@ -29,7 +29,6 @@ import (
"github.com/blevesearch/bleve/v2" "github.com/blevesearch/bleve/v2"
"github.com/blevesearch/bleve/v2/mapping" "github.com/blevesearch/bleve/v2/mapping"
"github.com/davecgh/go-spew/spew"
"github.com/iancoleman/strcase" "github.com/iancoleman/strcase"
) )
@ -214,7 +213,7 @@ func (s *searchHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
sr := bleve.NewSearchRequest(q) sr := bleve.NewSearchRequest(q)
sr.IncludeLocations = false sr.IncludeLocations = false
sr.Size = 25 sr.Size = 25
sr.Fields = []string{"page", "title", "text", "date"} sr.Fields = []string{"page", "title", "text", "date", "parent"}
sr.Highlight = bleve.NewHighlightWithStyle("html") sr.Highlight = bleve.NewHighlightWithStyle("html")
sr.Highlight.AddField("text") sr.Highlight.AddField("text")
results, err := s.searchIndex.Search(sr) results, err := s.searchIndex.Search(sr)
@ -230,13 +229,16 @@ func (s *searchHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
type pageBlock struct { type pageBlock struct {
ID string `json:"id"` ID string `json:"id"`
Title string `json:"title"` Parent string `json:"parent"`
Page string `json:"page"` Title string `json:"title"`
Text string `json:"text"` Page string `json:"page"`
Link []string `json:"link"` Text string `json:"text"`
Tag []string `json:"tag"` Link []string `json:"link"`
Date []time.Time `json:"date"` Tag []string `json:"tag"`
Date []time.Time `json:"date"`
Key string `json:"key"`
Value string `json:"value"`
} }
func (p pageBlock) Type() string { func (p pageBlock) Type() string {
@ -293,21 +295,24 @@ func createSearchObjects(rootBlockID string) ([]pageBlock, error) {
dates = append(dates, pageDate) dates = append(dates, pageDate)
} }
pageBlocks = append(pageBlocks, pageBlock{ block := pageBlock{
ID: current, ID: current,
Title: blocks.Texts[blocks.PageID], Parent: blocks.ParentID,
Page: blocks.PageID, Title: blocks.Texts[blocks.PageID],
Text: blocks.Texts[current], Page: blocks.PageID,
Link: linkNames, Text: blocks.Texts[current],
Tag: tags, Link: linkNames,
Date: dates, Tag: tags,
}) Date: dates,
}
queue = append(queue, blocks.Children[current]...) if kvpair := strings.SplitN(blocks.Texts[current], "::", 2); len(kvpair) == 2 {
} block.Key = strings.TrimSpace(kvpair[0])
block.Value = strings.TrimSpace(kvpair[1])
}
pageBlocks = append(pageBlocks, block)
if rootBlockID == "Henk_Stuifzand" { queue = append(queue, blocks.Children[current]...)
spew.Dump(pageBlocks)
} }
return pageBlocks, nil return pageBlocks, nil

@ -58,6 +58,7 @@
<a href="/graph/" class="navbar-item">Graph</a> <a href="/graph/" class="navbar-item">Graph</a>
<a href="/{{ .TodayPage }}" class="navbar-item">Today</a> <a href="/{{ .TodayPage }}" class="navbar-item">Today</a>
<a href="" class="navbar-item start-review">Review</a> <a href="" class="navbar-item start-review">Review</a>
<a href="" class="navbar-item start-sr">SR</a>
<a href="/auth/logout" class="navbar-item">Logout</a> <a href="/auth/logout" class="navbar-item">Logout</a>
<span class="navbar-item"><b>{{ $.Session.Me }}</b></span> <span class="navbar-item"><b>{{ $.Session.Me }}</b></span>
{{ else }} {{ else }}

Loading…
Cancel
Save