diff --git a/plugins/vocabbuilder.koplugin/db.lua b/plugins/vocabbuilder.koplugin/db.lua index 25f193560..041594ddc 100644 --- a/plugins/vocabbuilder.koplugin/db.lua +++ b/plugins/vocabbuilder.koplugin/db.lua @@ -203,21 +203,26 @@ end function VocabularyBuilder:insertOrUpdate(entry) local conn = SQ3.open(db_location) - - conn:exec(string.format([[INSERT INTO vocabulary (word, book_title, create_time, due_time) - VALUES ('%s', '%s', %d, %d) + local stmt = conn:prepare([[INSERT INTO vocabulary (word, book_title, create_time, due_time) + VALUES (?, ?, ?, ?) ON CONFLICT(word) DO UPDATE SET book_title = excluded.book_title, create_time = excluded.create_time, review_count = MAX(review_count-1, 0), - due_time = %d; - ]], entry.word, entry.book_title, entry.time, entry.time+300, entry.time+300)) + due_time = ?;]]) + stmt:bind(entry.word, entry.book_title, entry.time, entry.time+300, entry.time+300) + stmt:step() + stmt:clearbind():reset() self.count = tonumber(conn:rowexec("SELECT count(0) from vocabulary;")) conn:close() end function VocabularyBuilder:remove(item) local conn = SQ3.open(db_location) - conn:exec(string.format("DELETE FROM vocabulary WHERE word = '%s' ;", item.word)) + local stmt = conn:prepare("DELETE FROM vocabulary WHERE word = ? ;") + stmt:bind(item.word) + stmt:step() + stmt:clearbind():reset() + self.count = self.count - 1 conn:close() end @@ -229,13 +234,6 @@ function VocabularyBuilder:resetProgress() conn:close() end -function VocabularyBuilder:resetWordProgress(word) - local conn = SQ3.open(db_location) - local due_time = os.time() - conn:exec(string.format("UPDATE vocabulary SET review_count = 0, due_time = %d WHERE word = '%s';", due_time, word)) - conn:close() -end - function VocabularyBuilder:purge() local conn = SQ3.open(db_location) conn:exec("DELETE FROM vocabulary;") diff --git a/plugins/vocabbuilder.koplugin/main.lua b/plugins/vocabbuilder.koplugin/main.lua index efd281742..cd5a858c1 100644 --- a/plugins/vocabbuilder.koplugin/main.lua +++ b/plugins/vocabbuilder.koplugin/main.lua @@ -54,6 +54,8 @@ Menu dialogue widget --]]-- local MenuDialog = FocusManager:new{ padding = Size.padding.fullscreen, + is_edit_mode = false, + edit_callback = nil, tap_close_callback = nil, clean_callback = nil, reset_callback = nil, @@ -99,6 +101,14 @@ function MenuDialog:init() switch:setPosition(settings.enabled and 2 or 1) self:mergeLayoutInVertical(switch) + local edit_button = { + text = self.is_edit_mode and _("Resume") or _("Quick deletion"), + callback = function() + self:onClose() + self.edit_callback() + end + } + local reset_button = { text = _("Reset all progress"), callback = function() @@ -132,6 +142,7 @@ function MenuDialog:init() local buttons = ButtonTable:new{ width = width, buttons = { + {edit_button}, {reset_button}, {clean_button} }, @@ -451,7 +462,7 @@ function VocabItemWidget:initItemWidget() table.insert(self.layout, word_widget) - if self.item.review_count < 5 then + if not self.show_parent.is_edit_mode and self.item.review_count < 5 then self.more_button = Button:new{ text = "⋮", padding = Size.padding.button, @@ -477,7 +488,7 @@ function VocabItemWidget:initItemWidget() local right_side_width local right_widget - if self.item.due_time <= os.time() then + if not self.show_parent.is_edit_mode and self.item.due_time <= os.time() then right_side_width = review_button_width * 2 + Size.padding.large * 2 + ellipsis_button_width self.forgot_button = Button:new{ @@ -690,6 +701,9 @@ function VocabItemWidget:onGotIt() self.item.got_it_callback(self.item) self.item.is_dim = true self:initItemWidget() + if self.show_parent.selected.x == 3 then + self.show_parent.selected.x = 1 + end UIManager:setDirty(self.show_parent, function() return "ui", self[1].dimen end) end @@ -718,6 +732,7 @@ local VocabularyBuilderWidget = FocusManager:new{ show_page = 1, -- table of items item_table = nil, -- mandatory (array) + is_edit_mode = false, callback = nil, } @@ -746,7 +761,6 @@ function VocabularyBuilderWidget:init() self.item_width = self.dimen.w - 2 * padding self.footer_center_width = math.floor(self.width_widget * 32 / 100) self.footer_button_width = math.floor(self.width_widget * 12 / 100) - self.item_height = Screen:scaleBySize(72) -- group for footer local chevron_left = "chevron.left" local chevron_right = "chevron.right" @@ -834,6 +848,7 @@ function VocabularyBuilderWidget:init() bottom_line, self.page_info, } + self.footer_height = vertical_footer:getSize().h local footer = BottomContainer:new{ dimen = self.dimen:copy(), vertical_footer, @@ -853,13 +868,7 @@ function VocabularyBuilderWidget:init() show_parent = self, } - -- setup main content - self.item_margin = math.floor(self.item_height / 8) - local line_height = self.item_height + self.item_margin - local content_height = self.dimen.h - self.title_bar:getHeight() - vertical_footer:getSize().h - padding - self.items_per_page = math.floor(content_height / line_height) - self.item_margin = self.item_margin + math.floor((content_height - self.items_per_page * line_height ) / self.items_per_page ) - self.pages = math.ceil(DB:selectCount() / self.items_per_page) + self:setupItemHeight() self.main_content = VerticalGroup:new{} self:_populateItems() @@ -889,6 +898,17 @@ function VocabularyBuilderWidget:init() } end +function VocabularyBuilderWidget:setupItemHeight() + local item_height = Screen:scaleBySize(self.is_edit_mode and 54 or 72) + self.item_height = item_height + self.item_margin = math.floor(self.item_height / 8) + local line_height = self.item_height + self.item_margin + local content_height = self.dimen.h - self.title_bar:getHeight() - self.footer_height - Size.padding.large + self.items_per_page = math.floor(content_height / line_height) + self.item_margin = self.item_margin + math.floor((content_height - self.items_per_page * line_height ) / self.items_per_page ) + self.pages = math.ceil(DB:selectCount() / self.items_per_page) +end + function VocabularyBuilderWidget:nextPage() local new_page = math.min(self.show_page+1, self.pages) if new_page > self.show_page then @@ -983,6 +1003,9 @@ function VocabularyBuilderWidget:_populateItems() self.footer_right:enableDisable(self.show_page < self.pages) self.footer_first_up:enableDisable(self.show_page > 1) self.footer_last_down:enableDisable(self.show_page < self.pages) + if not self.layout[self.selected.y] or not self.layout[self.selected.y][self.selected.x] then + self.selected = {x=1, y=1} + end UIManager:setDirty(self, function() return "ui", self.dimen end) @@ -1019,6 +1042,12 @@ end function VocabularyBuilderWidget:showMenu() UIManager:show(MenuDialog:new{ + is_edit_mode = self.is_edit_mode, + edit_callback = function() + self.is_edit_mode = not self.is_edit_mode + self:setupItemHeight() + self:_populateItems() + end, clean_callback = function() self.item_table = {} self.pages = 0