mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Vocabulary builder: support manually adding words to vocabulary builder
This commit is contained in:
@@ -506,7 +506,7 @@ function DictQuickLookup:init()
|
||||
end
|
||||
end
|
||||
if self.tweak_buttons_func then
|
||||
self.tweak_buttons_func(buttons)
|
||||
self:tweak_buttons_func(buttons)
|
||||
end
|
||||
-- Bottom buttons get a bit less padding so their line separators
|
||||
-- reach out from the content to the borders a bit more
|
||||
|
||||
@@ -5,7 +5,7 @@ local LuaData = require("luadata")
|
||||
|
||||
local db_location = DataStorage:getSettingsDir() .. "/vocabulary_builder.sqlite3"
|
||||
|
||||
local DB_SCHEMA_VERSION = 20220730
|
||||
local DB_SCHEMA_VERSION = 20221002
|
||||
local VOCABULARY_DB_SCHEMA = [[
|
||||
-- To store looked up words
|
||||
CREATE TABLE IF NOT EXISTS "vocabulary" (
|
||||
@@ -17,6 +17,7 @@ local VOCABULARY_DB_SCHEMA = [[
|
||||
"review_count" INTEGER NOT NULL DEFAULT 0,
|
||||
"prev_context" TEXT,
|
||||
"next_context" TEXT,
|
||||
"streak_count" INTEGER NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY("word")
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS "title" (
|
||||
@@ -78,7 +79,13 @@ function VocabularyBuilder:createDB()
|
||||
ALTER TABLE vocabulary DROP book_title;]])
|
||||
end
|
||||
if db_version < 20220730 then
|
||||
db_conn:exec("ALTER TABLE title ADD filter INTEGER NOT NULL DEFAULT 1;")
|
||||
if tonumber(db_conn:rowexec("SELECT COUNT(*) FROM pragma_table_info('title') WHERE name='filter'")) == 0 then
|
||||
db_conn:exec("ALTER TABLE title ADD filter INTEGER NOT NULL DEFAULT 1;")
|
||||
end
|
||||
end
|
||||
if db_version < 20221002 then
|
||||
db_conn:exec([[ ALTER TABLE vocabulary ADD streak_count INTEGER NULL DEFAULT 0;
|
||||
UPDATE vocabulary SET streak_count = review_count; ]])
|
||||
end
|
||||
|
||||
db_conn:exec("CREATE INDEX IF NOT EXISTS title_id_index ON vocabulary(title_id);")
|
||||
@@ -140,6 +147,7 @@ function VocabularyBuilder:_select_items(items, start_idx)
|
||||
if item and not item.word then
|
||||
item.word = results.word[i]
|
||||
item.review_count = math.max(0, tonumber(results.review_count[i]))
|
||||
item.streak_count = math.max(0, tonumber(results.streak_count[i]))
|
||||
item.book_title = results.name[i] or ""
|
||||
item.create_time = tonumber( results.create_time[i])
|
||||
item.review_time = nil --use this field to flag change
|
||||
@@ -184,8 +192,9 @@ function VocabularyBuilder:gotOrForgot(item, isGot)
|
||||
local current_time = os.time()
|
||||
|
||||
local due_time
|
||||
local target_count = math.max(item.review_count + (isGot and 1 or -1), 0)
|
||||
if not isGot or target_count == 0 then
|
||||
local target_review_count = math.max(item.review_count + (isGot and 1 or -1), 0)
|
||||
local target_count = isGot and item.streak_count + 1 or 0
|
||||
if target_count == 0 then
|
||||
due_time = current_time + 5 * 60
|
||||
elseif target_count == 1 then
|
||||
due_time = current_time + 30 * 60
|
||||
@@ -205,11 +214,13 @@ function VocabularyBuilder:gotOrForgot(item, isGot)
|
||||
due_time = current_time + 24 * 30 * 3600
|
||||
end
|
||||
|
||||
item.last_streak_count = item.streak_count
|
||||
item.last_review_count = item.review_count
|
||||
item.last_review_time = item.review_time
|
||||
item.last_due_time = item.due_time
|
||||
|
||||
item.review_count = target_count
|
||||
item.streak_count = target_count
|
||||
item.review_count = target_review_count
|
||||
item.review_time = current_time
|
||||
item.due_time = due_time
|
||||
end
|
||||
@@ -217,6 +228,7 @@ end
|
||||
function VocabularyBuilder:batchUpdateItems(items)
|
||||
local sql = [[UPDATE vocabulary
|
||||
SET review_count = ?,
|
||||
streak_count = ?,
|
||||
review_time = ?,
|
||||
due_time = ?
|
||||
WHERE word = ?;]]
|
||||
@@ -226,7 +238,7 @@ function VocabularyBuilder:batchUpdateItems(items)
|
||||
|
||||
for _, item in ipairs(items) do
|
||||
if item.review_time then
|
||||
stmt:bind(item.review_count, item.review_time, item.due_time, item.word)
|
||||
stmt:bind(item.review_count, item.streak_count, item.review_time, item.due_time, item.word)
|
||||
stmt:step()
|
||||
stmt:clearbind():reset()
|
||||
end
|
||||
@@ -248,6 +260,7 @@ function VocabularyBuilder:insertOrUpdate(entry)
|
||||
ON CONFLICT(word) DO UPDATE SET title_id = excluded.title_id,
|
||||
create_time = excluded.create_time,
|
||||
review_count = MAX(review_count-1, 0),
|
||||
streak_count = 0,
|
||||
due_time = ?,
|
||||
prev_context = ifnull(excluded.prev_context, prev_context),
|
||||
next_context = ifnull(excluded.next_context, next_context);]]);
|
||||
@@ -308,7 +321,7 @@ end
|
||||
function VocabularyBuilder:resetProgress()
|
||||
local conn = SQ3.open(db_location)
|
||||
local due_time = os.time()
|
||||
conn:exec(string.format("UPDATE vocabulary SET review_count = 0, due_time = %d;", due_time))
|
||||
conn:exec(string.format("UPDATE vocabulary SET review_count = 0, streak_count = 0, due_time = %d;", due_time))
|
||||
conn:close()
|
||||
end
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ local ButtonTable = require("ui/widget/buttontable")
|
||||
local CenterContainer = require("ui/widget/container/centercontainer")
|
||||
local ConfirmBox = require("ui/widget/confirmbox")
|
||||
local Device = require("device")
|
||||
local DictQuickLookUp = require("ui/widget/dictquicklookup")
|
||||
local Event = require("ui/event")
|
||||
local Font = require("ui/font")
|
||||
local FocusManager = require("ui/widget/focusmanager")
|
||||
@@ -53,6 +54,47 @@ local subtitle_color = Blitbuffer.COLOR_DARK_GRAY
|
||||
local dim_color = Blitbuffer.Color8(0x22)
|
||||
local settings = G_reader_settings:readSetting("vocabulary_builder", {enabled = true})
|
||||
|
||||
local function resetButtonOnLookupWindow()
|
||||
if not settings.enabled then -- auto add words
|
||||
DictQuickLookUp.tweak_buttons_func = function(obj, buttons)
|
||||
if obj.is_wiki_fullpage then
|
||||
return
|
||||
elseif obj.is_wiki then
|
||||
-- make wiki window have the same button_tweak as its presenting dictionary window
|
||||
local widget = UIManager:getSecondTopmostWidget()
|
||||
if widget.tweak_buttons_func then
|
||||
widget:tweak_buttons_func(buttons)
|
||||
end
|
||||
return
|
||||
end
|
||||
table.insert(buttons, 1, {{
|
||||
id = "vocabulary",
|
||||
text = _("Add to vocabulary builder"),
|
||||
font_bold = false,
|
||||
callback = function()
|
||||
local book_title = obj.ui.doc_settings and obj.ui.doc_settings:readSetting("doc_props").title or _("Dictionary lookup")
|
||||
if book_title == "" then -- no or empty metadata title
|
||||
if obj.ui.document and obj.ui.document.file then
|
||||
local util = require("util")
|
||||
local directory, filename = util.splitFilePathName(obj.ui.document.file) -- luacheck: no unused
|
||||
book_title = util.splitFileNameSuffix(filename)
|
||||
end
|
||||
end
|
||||
obj.ui:handleEvent(Event:new("WordLookedUp", obj.word, book_title, true)) -- is_manual: true
|
||||
local button = obj.button_table.button_by_id["vocabulary"]
|
||||
if button then
|
||||
button:disable()
|
||||
UIManager:setDirty(obj, function()
|
||||
return "ui", button.dimen
|
||||
end)
|
||||
end
|
||||
end
|
||||
}})
|
||||
end
|
||||
else
|
||||
DictQuickLookUp.tweak_buttons_func = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function onShowFilter(widget)
|
||||
local sort_items = {}
|
||||
@@ -128,7 +170,7 @@ function MenuDialog:init()
|
||||
|
||||
-- Switch text translations could be long
|
||||
local temp_text_widget = TextWidget:new{
|
||||
text = _("Accept new words"),
|
||||
text = _("Auto add new words"),
|
||||
face = Font:getFace("xx_smallinfofont")
|
||||
}
|
||||
local switch_guide_width = temp_text_widget:getSize().w
|
||||
@@ -167,7 +209,7 @@ function MenuDialog:init()
|
||||
toggle = { _("off"), _("on") },
|
||||
values = {1, 2},
|
||||
alternate = false,
|
||||
enabled = settings.enabled,
|
||||
enabled = true,
|
||||
config = self,
|
||||
readonly = self.readonly,
|
||||
}
|
||||
@@ -247,7 +289,7 @@ function MenuDialog:init()
|
||||
RightContainer:new{
|
||||
dimen = Geom:new{w = switch_guide_width, h = switch:getSize().h },
|
||||
TextWidget:new{
|
||||
text = _("Accept new words"),
|
||||
text = _("Auto add new words"),
|
||||
face = Font:getFace("xx_smallinfofont"),
|
||||
max_width = switch_guide_width
|
||||
}
|
||||
@@ -319,8 +361,8 @@ end
|
||||
|
||||
function MenuDialog:onChangeEnableStatus(args, position)
|
||||
settings.enabled = position == 2
|
||||
self.context_switch.enabled = position == 2
|
||||
G_reader_settings:saveSetting("vocabulary_builder", settings)
|
||||
resetButtonOnLookupWindow()
|
||||
end
|
||||
|
||||
function MenuDialog:onConfigChoose(values, name, event, args, position)
|
||||
@@ -833,9 +875,11 @@ function VocabItemWidget:resetProgress()
|
||||
end
|
||||
|
||||
function VocabItemWidget:undo()
|
||||
self.item.streak_count = self.item.last_streak_count or self.item.streak_count
|
||||
self.item.review_count = self.item.last_review_count or self.item.review_count
|
||||
self.item.review_time = self.item.last_review_time
|
||||
self.item.due_time = self.item.last_due_time or self.item.due_time
|
||||
self.item.last_streak_count = nil
|
||||
self.item.last_review_count = nil
|
||||
self.item.last_review_time = nil
|
||||
self.item.last_due_time = nil
|
||||
@@ -1389,9 +1433,9 @@ function VocabBuilder:addToMainMenu(menu_items)
|
||||
table.insert(vocab_items, {
|
||||
callback = function(item)
|
||||
-- custom button table
|
||||
local tweak_buttons_func
|
||||
local tweak_buttons_func = function() end
|
||||
if item.due_time <= os.time() then
|
||||
tweak_buttons_func = function(buttons)
|
||||
tweak_buttons_func = function(obj, buttons)
|
||||
local tweaked_button_count = 0
|
||||
local early_break
|
||||
for j = 1, #buttons do
|
||||
@@ -1454,8 +1498,8 @@ function VocabBuilder:addToMainMenu(menu_items)
|
||||
end
|
||||
|
||||
-- Event sent by readerdictionary "WordLookedUp"
|
||||
function VocabBuilder:onWordLookedUp(word, title)
|
||||
if not settings.enabled then return end
|
||||
function VocabBuilder:onWordLookedUp(word, title, is_manual)
|
||||
if not settings.enabled and not is_manual then return end
|
||||
if self.builder_widget and self.builder_widget.current_lookup_word == word then return true end
|
||||
local prev_context
|
||||
local next_context
|
||||
@@ -1472,4 +1516,7 @@ function VocabBuilder:onWordLookedUp(word, title)
|
||||
return true
|
||||
end
|
||||
|
||||
-- register button in readerdictionary
|
||||
resetButtonOnLookupWindow()
|
||||
|
||||
return VocabBuilder
|
||||
|
||||
Reference in New Issue
Block a user