diff --git a/frontend/ui/widget/dictquicklookup.lua b/frontend/ui/widget/dictquicklookup.lua index 8135dd15b..f025ec214 100644 --- a/frontend/ui/widget/dictquicklookup.lua +++ b/frontend/ui/widget/dictquicklookup.lua @@ -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 diff --git a/plugins/vocabbuilder.koplugin/db.lua b/plugins/vocabbuilder.koplugin/db.lua index 83ce420ec..64e1de890 100644 --- a/plugins/vocabbuilder.koplugin/db.lua +++ b/plugins/vocabbuilder.koplugin/db.lua @@ -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 diff --git a/plugins/vocabbuilder.koplugin/main.lua b/plugins/vocabbuilder.koplugin/main.lua index 8ad00bd97..3295218a2 100644 --- a/plugins/vocabbuilder.koplugin/main.lua +++ b/plugins/vocabbuilder.koplugin/main.lua @@ -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